Geeks With Blogs

News

Hello,
My name is David Jacobus I am a former teacher of Computer Science and Mathematics, who is now working full time as a SharePoint Consultant! I have raced off-road motorcycles for 30+ years! I have fallen in love with Glamis and the Dune experience the last few years! My friends like to say: Jake, with age comes the cage! I suppose that is because at Glamis I use a Razor XP 900! Which has a full roll cage!


David Jacobus SharePoint Consultant

I was interviewing for a new position and one of the questions that was asked of me:  How would you overcome the limit of 10 overlays on the SharePoint 2010 calendar?  I answered, after a moments reflection,  that I would probably use some custom JavaScript and create a content type inheriting from the built-in Content Type Event.  A complete shot in the dark, as I had never had occasion to investigate this problem in all of my SharePoint development!  I did some Google\Bing investigation and looked at a few blogs and decided that my initial stab in the dark would be a way of accomplishing this feat!  So here is my take on this problem:  A complete solution that has all the bells and whistles needed that activates a few features and we have a working deployable calendar.   Some of the issues I saw with other solutions was that in using SPSite Data Query (Rollup) you either need to look for specific lists or use the template ID which would mean that you would roll up all calendars in the site collection or using specific lists, If a new calendar was added in the site collection the code would need to be changed.  Thus if we want to get calendars specifically created for rollup then we need a different content type.

 

Summary of what we are going to do:

 

1. Create an empty SharePoint 2010 project

2. Add some housekeeping folders.

3. Add some Modules to get our content into SharePoint

4. Create a new Content Type called RollUpCalendarContentType.  With associated artifacts.

5. Create the Calendar Web Part

6.  Create some Artifacts need to make the calendar work

7.  Complete the solution add a master with JQuery and a Page layout.

Project Source at CodePlex: ColoredCalendar

Create Empty SharePoint 2010 Project

image

Add new folder called Modules and add two Modules to this folder called CSS and Scripts.

image

 

Add JQuery to the scripts module and rename Sample.txt to calScripts.js

 

image

 

I have an Extension and Utilities Classes that I add to all my projects that will create Lists and Content Types.  They will be part of this Project at CodePlex

Create a Folder called Code and add these classes to the folder changing names spaces to reflect this project.  I know some would say create a DLL and reference that in your project but I have had occasion to use a 3rd party solution where the DLL was not available so I choose to keep my dependencies self contained as much as possible.  I won’t describe these artifacts as it is not germane to this blog entry.  I describe them in detail in a pervious post Creating Lists and Content Types :  List Instance

image

 

 

 

We need to create a Content Type that inherits from Event so lets create an Event Receiver and Create one.  When we added our Modules Visual Studio in its Goodness automatically added a Feature called feature1 let’s rename it to AddCalendarArtifacts this will be a feature that is site scoped so we can add the Scripts, CSS, Site Columns and Content Type within this feature.  The Scripts and CSS Modules are already added to this feature so we need to add an Event Receiver here to add our content type.

 

image

 

The difference between this content type and Event is that I will be adding a look up field which will lookup a a category from a List called  CalendarCategories  from  the Title column and a new column called MilCategory.   Therefore I need to create a list instance called “CalendarCategories”.  Since this list will only be instantiated at the Site Collection level we can add this list instance in this event receiver.  Here is the Event Receiver:

 

using System;
using System.Runtime.InteropServices;
using System.Security.Permissions;
using Microsoft.SharePoint;
using Demo.Calendar.Code;
using System.Collections;
namespace Demo.Calendar.Features.AddCalendarArtifacts
{

    [Guid("4c1beeb2-9bb5-488f-8220-53e2627b6ebe")]
    public class AddCalendarArtifactsEventReceiver : SPFeatureReceiver
    {
        const string columnGroup = "Demo";

        const string ctName = "RollUpCalendarContentType";

        // Uncomment the method below to handle the event raised after a feature has been activated.

        public override void FeatureActivated(SPFeatureReceiverProperties properties)
        {
            using (SPWeb spWeb = properties.GetWeb() as SPWeb)
            {


                if ((spWeb.Lists.TryGetList("CalendarCategories") == null))
                {
                    //create the list if it doesn't   exist
                    CreateCalendarCategoryList(spWeb);
                }
                //add the fields
                addFields(spWeb);

                //add content type
                SPContentType testCT = spWeb.ContentTypes[ctName];
                // we will not create the content type if it exists 
                if (testCT == null)
                {
                    //the content type does not exist add it
                    addContentType(spWeb, ctName);
                }
            }
        }

        public void addFields(SPWeb spWeb)
        {
            Utilities.addLookupField(spWeb, "CalendarCategories", "Title", "MilCategory", columnGroup);
        }

        private static void addContentType(SPWeb spWeb, string name)
        {
            SPContentType myContentType = new SPContentType(spWeb.ContentTypes["Event"], spWeb.ContentTypes, name) { Group = columnGroup };

            spWeb.ContentTypes.Add(myContentType);
            addContentTypeLinkages(spWeb, myContentType);
            myContentType.Fields.Delete("Category");
            myContentType.Update();
        }


        public static void addContentTypeLinkages(SPWeb spWeb, SPContentType ct)
        {
            Utilities.addContentTypeLink(spWeb, "MilCategory", ct);
        }

        private void CreateCalendarCategoryList(SPWeb web)
        {

            Guid newListGuid = web.Lists.Add("CalendarCategories", "Calendar Categories.",

                SPListTemplateType.GenericList);

            SPList newList = web.Lists[newListGuid];

            ArrayList choices = new ArrayList() { "Training", "Deploymment", "Deployed" };
            foreach (string iTem in choices)
            {
               SPListItem itemToAdd = newList.Items.Add();
                itemToAdd["Title"] =iTem;
                itemToAdd.Update();
              
            }
            newList.Update();

        }

    }
}

 

In addition we will need to create the Calendar List which can be Instantiated within any web in our site collection called RollupCalendar.  Thus we need a feature scoped to Web with an Event Receiver to create the List.

 

image

 

the code for this event receiver is:

 

using System;
using System.Runtime.InteropServices;
using System.Security.Permissions;
using Microsoft.SharePoint;
using Demo.Calendar.Code;
namespace Demo.Calendar.Features.AddCalendarList
{

    [Guid("8fa5c174-1c5a-4506-9204-7ffaf3a73dcc")]
    public class AddCalendarListEventReceiver : SPFeatureReceiver
    {
        const string columnGroup = "Demo";

        const string ctName = "RollUpCalendarContentType";

        public override void FeatureActivated(SPFeatureReceiverProperties properties)
        {
            using (SPWeb spWeb = properties.GetWeb() as SPWeb)
            {
                if ((spWeb.Lists.TryGetList("RollupCalendar") == null))
                {
                    //create the list if it dosen't to exist
                    CreatecalendarList(spWeb);
                }
            }
        }
        private void CreatecalendarList(SPWeb web)
        {
            Guid newListGuid = web.Lists.Add("RollupCalendar", "Custom Calendar.",
            SPListTemplateType.Events);
            SPList newList = web.Lists[newListGuid];
            newList.ContentTypesEnabled = true;
            var cal = web.Site.RootWeb.ContentTypes[ctName];
            newList.ContentTypes.Add(cal);
            newList.ContentTypes.Delete(newList.ContentTypes["Event"].Id);
            newList.Update();
            var view = newList.DefaultView;
            //add all view fields here
             SPContentType ct = cal as SPContentType;
            SPField field = ct.Fields.GetField("MilCategory");
            view.ViewFields.Add(field);

            view.Update();


        }

    }
}

Here is our Content Type deployed to the site:

 

image

 

Here is the Categories List:

 

image

 

Here is our  Rollup Calendar List:

image

 

Now we have the artifacts in-place to create our Calendar Web Part and test it.  Let’s add a web part to our solution

Okay now will create our Calendar Web Part.  I am modifying an MSDN demo so I will reference it here but I have changed it significantly to make it fit our usage.  The parts I found needed to be changed were references to web and of course the SPSiteDataQuery.  In addition,  we needed to make it really for rollup.

Here is the ASCX HTML:

 

<%@ Assembly Name="$SharePoint.Project.AssemblyFullName$" %>
<%@ Assembly Name="Microsoft.Web.CommandUI, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %> 
<%@ Register Tagprefix="SharePoint" Namespace="Microsoft.SharePoint.WebControls" Assembly="Microsoft.SharePoint, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %> 
<%@ Register Tagprefix="Utilities" Namespace="Microsoft.SharePoint.Utilities" Assembly="Microsoft.SharePoint, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
<%@ Register Tagprefix="asp" Namespace="System.Web.UI" Assembly="System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" %>
<%@ Import Namespace="Microsoft.SharePoint" %> 
<%@ Register Tagprefix="WebPartPages" Namespace="Microsoft.SharePoint.WebPartPages" Assembly="Microsoft.SharePoint, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
<%@ Control Language="C#" AutoEventWireup="true" CodeBehind="CustomCalendar.ascx.cs" Inherits="Demo.Calendar.CustomCalendar.CustomCalendar" %>
<SharePoint:SPCalendarView ID="spCalendarView" runat="server"> 
</SharePoint:SPCalendarView> 

Just inserting the SPCalendarView.

 

Here is the page code:

using System;
using System.ComponentModel;
using System.Web.UI.WebControls.WebParts;
using Microsoft.SharePoint;
using Microsoft.SharePoint.WebControls;
using System.Data;
using System.Text;
using System.Web.UI;
using Microsoft.SharePoint.Utilities;

namespace Demo.Calendar.CustomCalendar
{
    [ToolboxItemAttribute(false)]
    public partial class CustomCalendar : Microsoft.SharePoint.WebPartPages.WebPart
    {
        // Specifies the calendar for the add event. 
        static SPSite site = SPContext.Current.Site;
        private string strListName = "RollupCalendar";
        [WebBrowsable(true),
        WebDisplayName("Top Level Calendar Name"),
        WebDescription(""),
        Personalizable(PersonalizationScope.Shared),
        Category("Settings"),
        DefaultValue("Calendar Tools")
        ]
        public string _strListName
        {
            get { return strListName; }
            set { strListName = value; }
        }


        //public CustomCalendarWebPart()
        //{
        //}


        protected override void CreateChildControls()
        {
            string site = SPContext.Current.Site.Url;


            Microsoft.SharePoint.WebControls.CssRegistration cssLink = new Microsoft.SharePoint.WebControls.CssRegistration();
            cssLink.Name = site + "/Style Library/Demo/DemoCalendar.css";
            this.Page.Header.Controls.Add(cssLink);

            //this script add general javascript for the web part like showModal
            //ScriptLink scriptt1 = new ScriptLink();
            //scriptt1.Name = "~sitecollection/Scripts/calScripts.js";
            //scriptt1.Defer = true;
            //if (!this.Page.Header.Controls.Contains(scriptt1))
            //    this.Page.Header.Controls.Add(scriptt1);




            base.CreateChildControls();
            // Current web
            SPWeb web = SPContext.Current.Web;
            // List data
            DataTable results = GetQueryData(web);
            // Calendar Item Collection
            SPCalendarItemCollection items;
            if (results.Rows.Count > 0)
            {
                items = GetCalendarItems(web, results);
            }
            else
            {
                // Render header firstly:
                StringBuilder noResults = new StringBuilder();
                noResults.AppendLine("");
                noResults.AppendLine("");
                noResults.AppendLine("<font color='#05C4D8' size='4'>No Data Returned</font>");
                noResults.AppendLine("");
                Controls.Add(new LiteralControl(noResults.ToString()));
                return;
            }


            this.spCalendarView.EnableViewState = true;


            // Calendar Type
            if (!string.IsNullOrEmpty(Page.Request["CalendarPeriod"]))
            {
                this.spCalendarView.ViewType = GetCalendarType(Page.Request["CalendarPeriod"]);
            }


            // Binds a datasource to the SPCalendarView
            spCalendarView.DataSource = items;
            spCalendarView.DataBind();


            SPSecurity.RunWithElevatedPrivileges(
               delegate()
               {
                   // Check if current user can add events:
                   bool blnCanAddEvents = false;


                   using (web = SPContext.Current.Site.OpenWeb())
                   {
                       try
                       {
                           bool isHavePermissions = web.DoesUserHavePermissions(SPBasePermissions.AddListItems);


                           if (isHavePermissions)
                           {
                               blnCanAddEvents = true;
                           }
                       }
                       catch
                       {
                       }
                   }


                   // Render header firstly:
                   StringBuilder sbHeader = new StringBuilder();
                   sbHeader.AppendLine("");
                   sbHeader.AppendLine("");
                   sbHeader.AppendLine("<font color='#05C4D8' size='4'> </font>"); sbHeader.AppendLine("");
                   Controls.Add(new LiteralControl(sbHeader.ToString()));


                   //Render calendar secondly:     
                   Controls.Add(spCalendarView);


                   // Append Operation legend:

                   StringBuilder sbLegend = new StringBuilder();
                   sbLegend.AppendLine("<table align='center' width='100%' border='0'>");
                   sbLegend.AppendLine("<td width='50%' align='left' valign='top'>");
                   sbLegend.AppendLine("<b><u>Operation:</u></b><br /><br />");
                   string url = string.Format("{1}/Lists/{0}/NewForm.aspx", strListName, web.Url);

                   string java = string.Format("<li><a href=\"#\" onclick=\"javascript:showModal('Add Events', '{0}')\" >Add New Events</a></li>", url);

                   if (blnCanAddEvents)
                   {
                       //modal
                       sbLegend.AppendLine(string.Format("{0}", java));
                       //no modal
                       //sbLegend.AppendLine(String.Format("<li><a href=\"{1}/Lists/{0}/NewForm.aspx\">Add New Event</a></li>", strListName, web.Url));


                   }
                   sbLegend.AppendLine(String.Format("<li><a href='{1}/Lists/{0}'>View the Full Calendar</a></li>", strListName, web.Url));
                   sbLegend.AppendLine("</td></table>");
                   Controls.Add(new LiteralControl(sbLegend.ToString()));
               });
        }
        //sbLegend.AppendLine(String.Format("<li><a href=\"{1}/Lists/{0}/NewForm.aspx\">Add New Event</a></li>", strListName, web.Url));
        //<a href="#" onclick="javascript:showModal('Obligations', '/matt/Land/Lists/Obligations/calendar.aspx');">Obligations</a>

        /// <summary>
        /// Executes the query against the web and returns 
        /// results as DataTable.
        /// </summary>
        /// <param name="web">The web that is queried.</param>
        /// <returns>Query results as DataTable.</returns>
        private DataTable GetQueryData(SPWeb web)
        {
            var query = new SPSiteDataQuery();

            //no need to grab all calendars thus no servertemplate
            //query.Lists = "<Lists ServerTemplate=\"106\" />";
            //no need to grad lists by id need to know all lists before hand
            //            query.Lists = @"<Lists>
            //                      <List ID='{080BA3CB-9D7F-4E6B-AE02-2E5BFB79EF91}' />
            //                      <List ID='{B65A63B6-B857-423A-AE22-AA7957E78157}' />
            //                  </Lists>";
            //we are going to grab by content type thus nomral calendars will not be caught in the spsitedataquery
            SPContentType cTypeCollection = web.ContentTypes["RollUpCalendarContentType"];





            string where = string.Format(
                              @"<Where>
                    <BeginsWith>
                        <FieldRef Name='ContentTypeId'/>
                             <Value Type='Text'>{0}</Value>
                     </BeginsWith>
                  </Where>", cTypeCollection.Id);

            // Set the query string.
            query.Query = where;



            query.Webs = "<Webs Scope='SiteCollection' />";
            query.ViewFields = "<FieldRef Name='Title' />";
            query.ViewFields += "<FieldRef Name='ID' />";
            query.ViewFields += "<FieldRef Name='EventDate' />";
            query.ViewFields += "<FieldRef Name='EndDate' />";
            query.ViewFields += "<FieldRef Name='Location' />";
            query.ViewFields += "<FieldRef Name='Description' />";
            query.ViewFields += "<FieldRef Name='fAllDayEvent' />";
            query.ViewFields += "<FieldRef Name='fRecurrence' />";
            query.ViewFields += "<FieldRef Name='MilCategory' />";
            query.ViewFields += "<FieldRef Name='ContentType'/>";
            query.RowLimit = 100;


            return web.GetSiteData(query);
        }

        private SPCalendarItemCollection GetCalendarItems(SPWeb web, DataTable results)
        {
            // Create a new collection for the calendar items
            var items = new SPCalendarItemCollection();
            // SPCalendar Item
            SPCalendarItem item = null;


            #region Calendar Items which is got from the results
            // Loop results to get Calendar Item Information
            foreach (DataRow row in results.Rows)
            {
                // List Guid
                string guid = row["ListId"].ToString();



                // List
                SPList list = null;
                string site1 = null;
                string webid = row["WebId"].ToString();
                Guid webGuid = new Guid(webid);
                using (SPSite site = new SPSite(web.Site.ID))
                {
                    using (SPWeb subWeb = site.OpenWeb(webGuid))
                    {
                        Guid lGuid = new Guid(guid);
                        list = subWeb.Lists[lGuid];
                        site1 = subWeb.Title;
                    }
                }



                item = new SPCalendarItem();


                foreach (SPForm form in list.Forms)
                {
                    // Display Form Url

                    if (form.Type == PAGETYPE.PAGE_DISPLAYFORM)
                    {
                        item.DisplayFormUrl = form.ServerRelativeUrl;
                        break;
                    }
                }





                item.ItemID = row["ID"] as string;
                item.StartDate = DateTime.Parse(row["EventDate"] as string);
                item.EndDate = DateTime.Parse(row["EndDate"] as string);
                item.hasEndDate = true;
                item.Title = site1 + " " + row["Title"] as string;
                item.Location = row["Location"] as string;
                item.Description = row["Description"] as string;
                item.IsAllDayEvent = (int.Parse(row["fAllDayEvent"] as string) != 0);
                item.IsRecurrence = (int.Parse(row["fRecurrence"] as string) != 0);
                item.CalendarType = Convert.ToInt32(SPCalendarType.Gregorian);

                items.Add(item);
            }
            #endregion



            return items;
        }

        /// <summary>
        /// Gets the type of the calendar view.
        /// </summary>
        /// <param name="type">The type to be checked.</param>
        /// <returns>Correct view type of calendar.</returns>
        protected static string GetCalendarType(string type)
        {
            if (type == null)
                type = string.Empty;
            switch (type.ToLower())
            {
                case "day":
                    return "day";
                case "week":
                    return "week";
                case "timeline":
                    return "timeline";
                default:
                    return "month";
            }
        }

        protected override void OnInit(EventArgs e)
        {
            base.OnInit(e);
            InitializeControl();


        }

        protected void Page_Load(object sender, EventArgs e)
        {


        }
    }
}

I had a couple of hour detour, when I forgot to change the web part inheritance from WebPart to Microsoft.SharePoint.WebPartPages.WebPart .  So if you are following along, Make sure you do this as it will not error out but no binding will occur for the spCalendarView.  No Data!  but in debugging the web part it got the data?  hard problem to find!

As we parse this from top to bottom the first thing I need to do is make sure that the style for our calendar gets into the Style Library/Demo folder so looking at the elements.xml for that module I change it to:

 

<?xml version="1.0" encoding="utf-8"?>
<Elements xmlns="http://schemas.microsoft.com/sharepoint/">
  <Module Name="CSS">
    <File Path="CSS\DemoCalendar.css" Url="Style Library/Demo/DemoCalendar.css" />
  </Module>
</Elements>

The SPSiteDataQuery is using the ContentType vice list or template. 

 

Now the are some philosophical issues going on here.  Where do we put our JavaScript files, and more importantly, should our web part add them?   Web part, Page layout,  Master Page, etc..  I had the web part add the calScripts.js.  However,   One major problem I had was using a script from inside the site collection (database) vice the layouts folder.  I could not find a way to ensure a script was loaded after the built-in script calendar.js!  I knew a way from years of JQuery and general UI development to put it into an html page via a content editor web part.  So that’s what we are doing here!  I think there must be some way using:  ExecuteOrDelayUntilScriptLoaded or  LoadSodByKey("SP.UI.ApplicationPages.Calendar.js", function () {   WaitForCalendarToLoad(););  The script needs to be in a place where end users can modify it with SharePoint Designer or the UI.  Because, we don’t want to recompile and deploy a solution because a site changed or a new site was added.   So I put an html page inside the Style Library that is loaded into a Content Editor Web Part.  To complete the solution we need to add some other artifacts:  Master Page, Page Layout, and Build the Calendar Page in code.  I will provide the Code to build the Calendar Page and of Course the entire solution can be found at CodePlex.

I found through many trials and tribulations that if you build a page in code that has a web part dependency that is part of the solution, even if you make the feature dependent up on the web part activation, the page will not build correctly!  I think it is a timing issue with feature activation and running code.  This isn’t an issue if you manually activate the feature instead of Visual Studio doing it for you!  Therefore, I changed the default activation for the Build Pages feature to manual.

 

Here is the code for the feature Event Receiver to build the Calendar Page:

 

using System;
using System.Runtime.InteropServices;
using Microsoft.SharePoint;

using System.Reflection;
using System.Web.UI.WebControls.WebParts;

using Microsoft.SharePoint.WebPartPages;
using PublishingSite = Microsoft.SharePoint.Publishing.PublishingSite;
using PublishingPage = Microsoft.SharePoint.Publishing.PublishingPage;
using SPFile = Microsoft.SharePoint.SPFile;
using PublishingWeb = Microsoft.SharePoint.Publishing.PublishingWeb;
using PageLayout = Microsoft.SharePoint.Publishing.PageLayout;
using PublishingPageCollection = Microsoft.SharePoint.Publishing.PublishingPageCollection;

using System.Collections.Generic;
using Microsoft.SharePoint.Publishing.WebControls;
using Microsoft.SharePoint.Portal.WebControls;
using System.Xml;
using Demo.Calendar.Code;
using System.Collections;

namespace Demo.Calendar.Features.BuildCalendarPage
{
 
    [Guid("2165ad6d-3a2c-46f6-a266-ced544be57d4")]
    public class BuildCalendarPageEventReceiver : SPFeatureReceiver
    {

        private static void BuildCalendarPage(SPWeb web, PublishingPage pubPage)
        {
            // build the pages
            // Get the web part manager for each page and do the same code as below (copy and paste, change to the web parts for the page)
            // Partner Description
            SPLimitedWebPartManager mgr = web.GetLimitedWebPartManager(web.Url + "/Pages/Calendar.aspx", System.Web.UI.WebControls.WebParts.PersonalizationScope.Shared);


            // Instantiate the web parts
            ContentEditorWebPart ce1 = new ContentEditorWebPart();
            ce1.ChromeType = PartChromeType.None;
            ce1.Title = "Calendar";
            ce1.Hidden = true;

            ce1.ContentLink = "../Style Library/Demo/calendar.html";
            mgr.AddWebPart(ce1, "g_A6B6ABAB9A074688B118BCFE0E56D768", 1); //left top

            Demo.Calendar.CustomCalendar.CustomCalendar ccwp = new Demo.Calendar.CustomCalendar.CustomCalendar() { ChromeType = PartChromeType.TitleOnly, Title = "Calendar View" };

            mgr.AddWebPart(ccwp, "g_685594D193AA4BBFABEF2FB0C8A6C1DD", 1);//head
            pubPage.Update();
        }

        private static void checkOut(string pagename, PublishingPage p)
        {
            if (p.Name.Equals(pagename, StringComparison.InvariantCultureIgnoreCase))
            {

                if (p.ListItem.File.CheckOutType == SPFile.SPCheckOutType.None)
                {
                    p.CheckOut();
                }

                if (p.ListItem.File.CheckOutType == SPFile.SPCheckOutType.Online)
                {
                    p.CheckIn("initial");
                    p.CheckOut();
                }
            }
        }
        private static void checkin(PublishingPage p, PublishingWeb pw)
        {
            SPFile publishFile = p.ListItem.File;

            if (publishFile.CheckOutType != SPFile.SPCheckOutType.None)
            {

                publishFile.CheckIn(

                "CheckedIn");

                publishFile.Publish(

                "published");
            }
            // In case of content approval, approve the file need to add
            //pulishing site 
            if (pw.PagesList.EnableModeration)
            {
                publishFile.Approve("Initial");
            }
            publishFile.Update();
        }
        public override void FeatureActivated(SPFeatureReceiverProperties properties)
        {



             //create the publishing pages

            using (SPWeb spWeb = properties.GetWeb() as SPWeb)
            {
                CreatePublishingPage(spWeb, "Calendar.aspx", "ThreeColumnLayout.aspx", "Planing Calendar");



            }



        }




        private void CreatePublishingPage(SPWeb site, string pageName, string pageLayoutName, string title)
        {
            PublishingSite pubSiteCollection = new PublishingSite(site.Site);
            PublishingWeb pubSite = null;
            if (pubSiteCollection != null)
            {
                // Assign an object to the pubSite variable
                if (PublishingWeb.IsPublishingWeb(site))
                {
                    pubSite = PublishingWeb.GetPublishingWeb(site);
                }
            }
            // Search for the page layout for creating the new page
            PageLayout currentPageLayout = FindPageLayout(pubSiteCollection, pageLayoutName);
            // Check or the Page Layout could be found in the collection
            // if not (== null, return because the page has to be based on
            // an excisting Page Layout
            if (currentPageLayout == null)
            {
                return;
            }


            PublishingPageCollection pages = pubSite.GetPublishingPages();
            foreach (PublishingPage p in pages)
            {
                //The page allready exists
                if ((p.Name == pageName)) return;

            }



            PublishingPage newPage = pages.Add(pageName, currentPageLayout);
            newPage.Description = pageName.Replace(".aspx", "");
            // Here you can set some properties like:
            newPage.IncludeInCurrentNavigation = true;
            newPage.IncludeInGlobalNavigation = true;
            newPage.Title = title;






            //build the page 


            switch (pageName)
            {
                case "Calendar.aspx":
                    checkOut("Calendar.aspx", newPage);
                    BuildCalendarPage(site, newPage);
                    break;
                default:
                    break;
            }
            // newPage.Update();
            //Now we can checkin the newly created page to the “pages” library
            checkin(newPage, pubSite);


        }

        /// <summary>
        /// Find a page layout in the layoutcollection based on the templatename
        /// </summary>
        /// <param name="pubSiteCollection">The toplevel publishing site</param>
        /// <param name="templateName">Name of the pagelayout</param>
        /// <returns>Pagelayout if excists or null</returns>
        private PageLayout FindPageLayout(PublishingSite pubSiteCollection, string templateName)
        {
            Microsoft.SharePoint.Publishing.PageLayoutCollection plCollection = pubSiteCollection.GetPageLayouts(true);
            foreach (Microsoft.SharePoint.Publishing.PageLayout layout in plCollection)
            {
                // String Comparison based on the Page Layout Name
                if (layout.Name.Equals(templateName, StringComparison.InvariantCultureIgnoreCase))
                {
                    return layout;
                }
            }
            return null;
        }
        public static void setWebPartProperties(System.Web.UI.WebControls.WebParts.WebPart webPart, string webPartName, Dictionary<string, string> props)
        {
            if (string.Equals(webPart.GetType().ToString(), webPartName))
            {
                PropertyInfo[] pinProperties = webPart.GetType().GetProperties(BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance);



                foreach (KeyValuePair<string, string> p in props)
                {
                    foreach (PropertyInfo pinProperty in pinProperties)
                    {

                        if (pinProperty.Name == p.Key)
                        {
                            pinProperty.SetValue(webPart, p.Value, null);
                            break;
                        }
                    }

                }
            }
        }
    

    }
}

Now that we have all of this in a solution, Why not just build a web template?  I think it is and a topic for another blog entry!

Here is a screen shot with the project deployed and activated:

 

 

Click and add a new site, Name it Subsite1: 

image

 

Go to Settings and activate the site feature:

 

image

 

Go to View all Site Content and click on RollupCalendar add a test entry:

 

image

Go back to the Calendar page:

image

 

For Demo purposes I will create a sub site I know is not in the JavaScript,  I will create a sub site named:  NewSite and added the roll up calendar with a dummy test entry,  if we go back to the Calendar page we will see the entry but without any color:

 

image

I have dummy site names in the calendar.html (JavaScript) so if we add a site not on the original rollout then open the Calendar.html in SharePoint Designer:

 

image

 

Notice there isn’t any site named NewSite, Change one of the unused entries to NewSite (These are caps sensitive).

 

image

 

Last thing is how we change colors on the calendar.  Just open up DemoCalendar.css for the Styles library:

 

image

I have entries in here for 5 sites.  Notice it is a style for the class and its link to fine tune the style.  Use your design skills!Smile  I added the feature to change the master page of the site to ensure JQuery.

 

For development,  Create a new site collection,  activate the features,  There are some dependencies, which might come in to play if you deploy this from visual studio.  If that happens, just redeploy!  it will fix it!.  You will know if everything deployed correctly if the Calendar page deploys approved.  II f it doesn't  delete the page and reactivate the feature.

Posted on Wednesday, November 20, 2013 9:13 AM | Back to top


Comments on this post: SharePoint Custom Calendar with JQuery Colors

No comments posted yet.
Your comment:
 (will show your gravatar)


Copyright © David Jacobus | Powered by: GeeksWithBlogs.net