Loading JavaScript via CustomAction and Initializing Functions with SharePoint 2013’s Minimal Download Strategy

9 Apr

For any of you who have worked with the new SharePoint 2013 Minimal Download Strategy (MDS) and custom scripts, you have probably run into some of the same headaches as myself.

While “official” documentation on MDS is greatly lacking (surprise, surprise), there are some great articles out there that really helped me build a foundational understanding. However most are focused around the use of custom scripts in conjunction with JSLink and tend to assume all the JavaScript references are embedded in the master page. So if you are in the same boat, check out the my reference section at the bottom as I have listed some of the better articles that are great reads and very helpful.

Scenario

Current project requires implementing multiple host names site collections, each with their own branded custom master page, and include about 20 different core scripts that are needed for various features and functionalities (such as jQuery, Knockout, Bootstrap, Amplify, etc.). Each master page will then load client-side initialization functions for a handful custom features, the most common being a world clock.

Solution v1.0

From a maintenance standpoint, loading my scripts via Custom Actions in a single Site feature is a much better and simpler solution than creating a ScriptLink and listing out each of the 20 core scripts in all the master pages and then having to add/remove them when the project requirements change or additional enhancement phases are started.

Loading JavaScript via CustomActions

Specifically, I need a way that once the page is loaded that I am able to initialize and world clock component that is being shown on the page, which utilizes jQuery, Knockout, and a custom Utility class. To do so I have initialization scripts that are directly tied to each master page via a ScriptLink reference so that I can have a different Custom and System master page for each site and can fire off additional, master page specific initializations that might be needed, which means I can’t use a CustomAction for those scripts.

ScriptLink LoadAfterUI

Wall Ramming

Attempt 1

This concept works great when MDS is disabled or when Publishing is enabled as Publishing negates MDS. However, when using MDS, any time a partial load fires, noted by “/_layouts/15/start.aspx#” displaying in browser address bar, my initialization script is called before the CustomActions have fired to load the core scripts and subsequently errors out.

MDS Undefined Error

After reviewing a lot of different articles, the common thread was to create a non-anonymous function (in my case within a Singleton object) and register it with SharePoint’s RegisterModuleInit() function.

MDS Attempt 1

Note: As you can see above, I do have a delay in place to wait until the body and SP.js is loaded, so I can rely upon _spPageContextInfo to always be populated.

I would like to say that worked, that doesn’t cover everything situation, or rather only works when the MDS partial page load is in play. See also:


Attempt 2

Now that I have my solution partially responding, I wanted to figure out what the trigger was to get it to fully function as expected. Upon diving deeper into Anatoly’s post I saw he ran into a similar quirk and so I attempted to use the $_global_ trick that worked for him. I had some mixed results with this solution. My best guess is it has to do with my utilizing CustomActions to load my core scripts or during testing I didn’t add $_global_ to all my core scripts. Either way, it would have been A LOT of files to modify, including 3rd party scripts as well as providing training to the client on the concept was not ideal. So I figured there had to be another way.

After walking through a lot of trial and error debug sessions, and thanks to insight from Sridhar’s CSR-override on MDS post, the simplest solution I found was to check to see if my core utility object was already loaded and if so call my initialization function directly, otherwise I assume MDS is in effect and I register my function to fire once MDS has completed.

MDS Attempt 2

Resolution

Once I implemented the combination of Attempt 1 and Attempt 2, everything now appears to be functioning as expected. I am not sure if this concept will work when using JSLink, but again, here are some really great resources to reference:

VERY IMPORTANT: One thing I want to make sure to point out that the ScriptLink for the initialization script in the master page must include LoadAfterUI=”True” or it will not initiate correctly. I was reminded of this the hard way when I redeployed one of my master pages without this and my script stopped fired after a partial MDS load.

Final Result is that each and every time my core scripts are being loaded before my initialize initialization script so my world clock which is now displaying on both full and partial loads.

MDS Resolution

Summary

In this post my goal was to get a custom script to initialize after scripts loaded via CustomActions in conjunction with a site using Minimal Download Strategy (MDS). Here are key factors that are required in order to get this working:

  • Initialization script must be referenced in a ScriptLink that has the property of LoadAfterUI set to “True”
  • Initialization script’s primary function must be a named function and not anonymous
  • When calling the named initialization function, you must register it to fire after MDS is completed using the RegisterModuleInit() function


References

Edit mode panel does not render at all on system pages

18 Jul

This one is a pretty odd one.

we had the need to emit some different css based on if a page was in edit mode or in display mode on a recent project, and so we put two edit mode panels on the master page.

one with PageDisplayMode set to display.. and the coresponding HTML that we wanted to render..

and another edit mode panel set to edit that renders the other one.

Now, keep in mind there are only two settings for that flag. display or edit.

Worked great, went to our pages, detail pages, list pages, web part pages etc.. edited the page.. and all the changes we expected to see were there and happy.

Now, I repeat, keep in mind there are ONLY two settings for that flag. display or edit.

We then went to a system page, view all site content or site settings.. and the branding/design was ALL kinds of messed up? what gives?

As it turns out, the edit mode panel for some reason.. rendered nothing.

neither edit mode panel was rendered. Which I would have *assumed* would have been impossible since we had a panel configured for every possible option. and Since this was the same master page everything else was using.

and so since this is SharePoint.. my assumptions were wrong.

So there is either a secret third option? or some weird change that only the system pages make.

I don’t know, we ended up finding another approach that did not use edit mode panels.. but this was something I could not find any blog posts about.

So heads up. Edit model panels.. on master pages.. don’t render at all on certain system pages.

 

SP2013 disables org chart viewer.. but only on YOUR profile page

1 Jul

Put this in the strange but true category.

We received a defect report from a client doing a 2013 migration stating that the org chart viewer wasn’t working. Gave us a link to the page where it wasn’t working. Of course we went to verify the defect, but when we looked the org chart viewer was there.

Thought that was closed, but they insisted it wasn’t there. So assuming it was some sort of training issue, we went to show them where the viewer was and how to get to it. But when we went to see the same page on thier machine.. no Org chart. what?

So we went to a few other peoples profile pages. All of them worked. Just not theirs. Was this some wierd cache issue? Had they customized their page in a way that broke this?

Well with this new information, we went back to look at our own profile page. And turns out when anyone looks at their own profile, they cannot see the org chart viewer. So thinking this must be a bug, we went to go find a bug report from someone else, and hopefully find a fix or work around.

This was the post we found: http://blogs.msdn.com/b/chandru/archive/2013/04/01/sp15-organization-chart-in-mysites.aspx

Granted the date on the post is April Fool’s day, which always makes me suspicious. But concerns aside, it basically indicates, “yeah it does that because we thought turning it off was better than making it perform better”. And we did find another post not on April Fool’s Day, that matches the comments, and even links to that post. (http://social.technet.microsoft.com/forums/sharepoint/en-US/71046c9d-b7f6-4cff-81dd-5edf67bd9e11/sharepoint-2013-issue-with-org-chart-not-visible)

So there you have it, by design, and if you want it, custom event reciever and feature stapling to fix it. (unless I assume you are in office 365, then you are out of luck)

 

Misleading VS message trying to deploy a solution

17 Jun

I was working on a SP2010 project and working from a box I did not build, and I was getting the following error when trying to deploy my solution:

Error occurred in deployment step ‘Recycle IIS Application Pool’: Cannot connect to the SharePoint site: http://xxx/. Make sure that this is a valid URL and the SharePoint site is running on the local computer. If you moved this project to a new computer or if the URL of the SharePoint site has changed since you created the project, update the Site URL property of the project

I thought, That’s odd I am pretty sure I am a local admin.

Double checked, sure enough I was, I should be able to do an IISreset.

So I pulled up a command line and was in fact able to successfully run an IISreset. But still was getting this error from VS.

I saw some threads that indicated I may need to also be a site collection Admin in order to do the IISreset from VS during a deploy. So I checked, I was a site collection admin, but still was getting the error from a VS deploy.

For fun I thought lets close and restart Visual Studio, no help. Restart the box, no help.

Did a little more digging and came across this thread.

http://mushannak.blogspot.com/2013/02/error-occurred-in-deployment-step.html

That was it, the local DB did not have my account as the owner on the content database.

Changed that and I was able to successfully deploy, no thanks to that error message though.

User picture error on video player page

14 May

Ran into this issue.

The user profile picture show on the OOTB video player page renders as a red x/broken link.

2013-05-14_1442

inspecting the link the URL has instead of %20 for spaces in the path to the image.. has %2520.. what is that? dunno?

I confirmed that the page was the out of the box videoplayerpage.aspx

Looks like it is a bug and you have to edit the page manually for the profile picture links to render correctly.

A quick search for the page name and 2520 turned up this link.

http://social.technet.microsoft.com/Forums/en-US/sharepointgeneral/thread/b8e415d5-b213-4d7c-bd8f-b4f1eb3f54ab/

Extra annoying, so heads up on that one

Careful when you import that design manager package (part 2)

10 May

After my last post we started looking for more possible content type corruption introduced by Design Manager Export/import process.

it appears to impact other content type besides just “page”. we are seeing corruption in “article page” and “welcome page” as well.

article page is missing:

  • Page content, Summary Links, Byline, Article Date, Image Caption

Welcome page is missing:

  • Page content, Summary Links, Summary Links 2

working on documenting all the content types that are not being exported fully.