2013-12-11

Originally posted on: http://geekswithblogs.net/djacobus/archive/2013/12/11/154856.aspx

My second post dealing with the full calendar web JQuery plugin.  In the first post, I used some plumbing from a previous project and Added the Full Calendar plugin.  A few people have asked me to make this a sandbox solution and to have the web part add everything it needs to run, JavaScript, Style Sheets, etc. Do not muck it up with all the other artifacts like master pages, etc..  Okay, I took this task on and learned so many new nuances' in the process!  I have hear from many people including myself that SharePoint is such a large platform that many issues come up that are Tribal, not documented, and only learned through the school of hard knocks!



The above is a team site with a full calendar web part on the page:  Two sites are using OOTB calendars, this site SubSite1 and Demo the site collection root!   I had one friend tell me that the OOTB calendar can be color coded, so why would we want this one?  Well,  the point is valid,   if you need more than 10 overlays then you need an alternate calendar, which this is one of many such solutions and it is free.  The gist of this post is not the product but in the trials and tangents caused from turning a relatively easy server side product into a sandbox server side product.  

Here is the web part preview from the gallery:



The point here, is the web part is not dependent on anything from the page.  It is up and styled appropriately  Clicking on an event will bring up the event in typical SharePoint modal dialog for viewing and if you have the permissions editing!

 



Here is a summary of the issues:

1.  The SharePoint ScriptLink and CSSRegistration  controls are not supported in sandbox solutions!

a.  How do we get our CSS and JavaScript into our solution in the correct order?

2.  LimitedWebPartManger is not available in sandbox solutions.

a.  We can’t build the page in code without it!

b.  We will need to build the page declaratively.

3.  SPCalender is not available in a sandbox solution

a.  We will need to create our own collection

Here is a Summary of what was done in this project:

 

1.  I started a new sandbox solution, so I didn’t have any old artifacts causing issues later on.   I added some folders for artifacts I knew I would be using:  a Modules folder and inside I created modules for CSS, Scripts, SitePages, and later CustomActions.

2.  I added a WebPart: FullCalendar

a.  Most of the work and tangents were done here.

3.  I added an entity Calendar, as we would need it for our collection as we cannot use the OTTB SPCalendarItemsCollection in a sandbox solution

No fancy getters and setters, it is just a holder for events. 

Here is the project code:  SkyDrive

Okay, Solving the first issue: ScriptLink and CSSRegistration  took a long time trying different idea’s on how to use get JavaScript onto the page in the correct order.   There is at least three way’s in which I tried which worked sometimes incrementally, meaning the CSS or JavaScript got added in the wrong order.  Not a good situation if your using a JQuery plug-in before JQuery gets loaded.   The ScriptLink and CSSRegistration controls allow for this even when using content from the database vice the layouts folder!  OH well,  I banged my head against the wall a few times, looked at a few blogs and then found a couple on custom actions which was just the ticket I needed to get the general JavaScript on the page in the correct order, by that I mean JQuery, JQuery UI, and JQuery Full calendar.  So I added them in a custom action which I install with a module.  Notice, we are able to use the ~SiteCollection pointer here.

There should be some discussion here, as what if JQuery is already loaded from the master page, etc..  We certainly don’t want web parts adding these general purpose scripts, especially if we are doing team development!   So user just be aware that these are being added as part of this solution.  In addition, I am creating the page to house this web part as part of this solution.   We still haven’t gotten our specific JavaScript onto the page which we want after our web part loads, as this script is the one that changes colors for the events and our Modal code.  This one has caused me havoc on two projects, It is old age I suppose, as the solution was simple enough once I thought it through.  I just said it!  Loaded after the Full Calendar web part is loaded.  So I learned a little bit about web part life cycle, and what happens in what order.  I certainly didn’t want my JQuery code loaded in the head of the page even when using JQuery  $(document).ready(function () {   colorIt(); });  It loaded and ran before the web part events were added to the page.    I read a blog which discusses using some OOTB framework to do this, and of course the old spBodyOnLoadFunctionNames.push which I could not get to work.   Oh well, I have a solution from another blog which fits perfectly:

Notice I am not adding these to the Page head.  These are being added to the page, The two style sheets before the web part loads and the local script after the web part loads.  I use Fiddler all the time when doing web part development as it lets me see if I have any orphan artifacts laying around during development. 

  

The Scripts are all loading in the correct order, all good to go!  Below is a fragment of the page source showing the events, CSS, and the Scripts on the page.

Okay, we have the web part working, I will discuss the code summary here:

 

1.  Use the SPSiteDataQuery to roll up events from all calendars in the site collection. 

2.  Execute the query and get the data from a data table and convert the data into a custom Calendar collection

3.  Use the Calendar Collection to create a Full Calendar event for each calendar event in the site collection.

4.  Use the Full Calendar event.Url to call our custom JavaScript OOTB SharePoint Modal Dialogs to Access the Calendar events in SharePoint.

I use some cool code that I got from MSDN to get the form Url for each event highlighted below:

The SPSiteDataQuery to me seems only useful for sites which have tight control over calendars because it gets all calendar events across the site collection.  I put up another project on codeplex which was more involved with content types, etc.  Which just uses a content type inherited from events so a rollup can occur from that content type thus calendars across the site that which are created using that content type.  I like this better than using specific list GUID’s as if you need a new calendar added in the site collection then you need to recompile and push another change. Of course being a sandbox solution this becomes trivial. 

The actual web part code to get the events into Full Calendar seems trivial now that it has been written but a lot trial and many errors; However, the FullCalendar documentation is excellent and very robust.  I was able to add the code to use the OOTB SharePoint modal framework very easily and little effort! Line breaks have been added so don’t copy and paste.  The source is available above.

Okay, all my other projects, I have built publishing pages in code but for sandbox solutions the SPLimitedWebPartManager is not available; therefore code is not going to work!  We need to use a module and page template to create our pages in a sandbox solution.  In this project, I am only building one page but the template could be used for many pages in a large project.  I found many gotcha’s here that are not documented in one place but through research on the web.  The first is with the xml for the page module:

When creating a module for the page you need to insert and ALLUsersWebPart :

Here we have a module with a template file which will provision a page:  FullCalendar.aspx.  On the page the web part is added via the AllUsersWebPart element.  The gotcha is that I saw that this is just the web part file which is in the web part gallery so I downloaded it as copy and pasted it in-between the CDATA elements; However, I read a blog that said you needed to remove the <webParts> elements.   When I did this, I kept getting an error about an Unknown XML Namespace??  What, I discovered is that the blog writer was right, if I was provisioning a V2 web part, not V3.   The other is the solution ID is needed in the sandbox solution.  I say this because my first attempt at this I used the actual web part xml from the solution which is:

 

I replaced the $SharePoint.Project.AssemblyFullName$ with the 4 part assembly name and thought I was good to go!  NO! As you can see the solution ID element is missing.  The error I got was that SharePoint couldn’t find the code.   I chased that on for a few hours.  Okay! wow! I finally, got a web part page provisioned without code in a sandbox solution and I can repeatedly use this in other projects to provision pages vice code in a feature receiver which had timing problems when web parts were being provisioned in the same project as the page being built using Visual Studio to activate features.  If features were activated manually the code worked.  I have an Office 365 site and I have tried adding this code but it doesn't work.  I also have an Azure site so I will try and set up remote debugging through the Azure service bus and see what the issue is.  I decided to post this as is for on premise SharePoint and fix the post when I figure out what is going on in the cloud!

The final Piece is the custom script to color the calendar and display the modal:

 

Show more