Tuesday, April 28, 2015

How to run code after all CSWP’s have finished

image
My colleague Gissur at Puzzlepart asked me if I knew how he could run some piece of JavaScript after all his CSWP’s were done rendering. He has 19 WP’s on the page all collapsed by default with CSS, and wanted the first one with content to be expanded upon page load.

He could have gone the content routing approach which I’ve blogged about previously, but as he has paging per web part, that would not work.
Programmatically the challenge is not too hard as you want to keep count of all the rendered web parts, and when the last one is done you know you are ready to go. A pattern often used and probably a use-case others might have as well.

To help Gissur and anyone else with this challenge I came up with the code below. There might be other approaches, but it's short and not too complicated.

Make sure you add the code as a post-render callback to the control template of all the web parts you want to include in the wait for all behavior.

I’ve tested it on a page a with 20 CSWP’s on it, some also set to work asynchronously, and it seems to work pretty good.

AddPostRenderCallback(ctx, function(){
    // loop over all queries on the page
    var allRendered = true;
    for (var group in Srch.ScriptApplicationManager.get_current().queryGroups) {
        var displays = Srch.ScriptApplicationManager.get_current().queryGroups[group].displays;
        if (displays.length > 0 && !displays[0].get_renderedResult() && displays[0].get_visible()) {
            //check if results are rendered
            allRendered = false;
        }
    }
    if(allRendered) {
        console.log("DONE!!!!");
    } else {
        console.log("WAIT FOR IT!!!!");
    }
});


The research to get this working was finding Srch.ScriptApplicationManager.get_current().queryGroups and then finding which object and function returned what I needed. The clue is that all web parts share the same ScriptApplicationManager which allows you to snoop what the other web parts might be doing.