Archive

Archive for March, 2014

SharePoint 2013 Ratings and Internet Explorer 10+

18 March 2014 7 comments

You may have noticed that the star ratings have changed in SharePoint 2013 to utilise the theme of the site, or you may not.  If you haven’t seen them they look like this…

classification

Well most of the time they look like that. But sometimes, when using IE10 or above, they look like this…

classification2

So what is going on here?  After some looking at the code, decompiling, investigating it seems to be an sequencing problem.  Here’s my breakdown.

The RatingFieldControl renders the following HTML:

<span id="RatingsCtrl_ctl00_PageOwnerRviewDateBar_..."></span>
<script type="text/javascript">
    EnsureScript('SP.UI.Ratings.js', typeof(SP.UI.Reputation), function() {
        // Do Stuff
    });
</script>
<div style="display: none;">
    <img id="RatingsLargeStarFilled.png" src="themedfile"></img>
    <!-- other img tags for different parts of the ratings -->
</div>

Well obviously it is is a little more, I’ve distilled it down to the basics.  The first span is filled in by the function included in the script tag.  The last hidden div is used for the script to populate the image files that are required.  And therein lies the problem.

When using fiddler to investigate the problem with rendering in IE10. I could see that the loading sequences when I pressed enter in the address bar vs pressing the refresh button vs using IE8/9 were different.

When the display bug occurs it appears that the EnsureScript, which is part of the Script on Demand libraries, executes immediately since SP.UI.Reputation is already loaded.  This means that when the script goes to find the images it can’t find them because they haven’t been rendered to the page yet.  The simple fix is for Microsoft to change the rendering sequence for their control, as there are private methods involved it isn’t possible for us to just overwrite the render method, and even if we did then our control wouldn’t be the one used in most cases.

There are two solutions I can think of:

1. Calculate the themed source files and specify the images yourself.  This is probably not ideal as a change in the theme will change the files you want to point to, and these can’t be predicted.

2. Re-execute the script after the page has completed rendered to the browser.

I’m going to look at using option 2:

Without going into full details, here is the solution add this JavaScript to the page (I already have jQuery library loaded):

$(function () {
    if (SP.UI.Reputation != null) {
        SP.UI.Reputation.RatingsHelpers.$c(false);
        $('[id^=RatingsCtrl_] ~ script').each(function() { 
            eval($(this).text());
        });
    }
});

How does this solve the problem?

The first line is shorthand for wait for the document.ready event so ensures the script isn’t loaded until after the page has finished loading.

The IF statement detects if the SP.UI.Ratings.js. I could use the EnsureScript here as well, but by checking this way, if the script is still waiting to be loaded then the emitted script above will still be waiting to execute so we won’t need our little hack.

The function line 3 calls the RatingsHelper method responsible for the reading of the img tags for use by the script and thus forces these to be reloaded.

The last block finds, using jQuery selectors, the script blocks associated with the Ratings controls and executes these statements again.  Forcing the display of the star ratings to be updated correctly.

And there you have it, the simplest hack I could find to correct what could easily be done by Microsoft switching a few lines of code around.

Advertisements
Categories: Programming, SharePoint