Tuesday, April 28, 2015

How to run code after all CSWP’s have finished

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) {
    } 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.

Thursday, April 23, 2015

Restarting your Search Host Controller will impact People Search

We’ve had issues with people search not working in two environments which was solved by adding the search service account to the WSS_ADMIN_WPG local group on all search servers. The issue is that if the search service account is not part of this group it cannot read the projection model files needed to perform fuzzy name search.

You can read more about this issue over at Ron Grzywacz’s blog.

Tuesday, April 14, 2015

An approach to list all external users in your SharePoint Online enviroment


Kirk Liemohn recently asked a question on the Office 365 Yammer network if there was an API to list all the external users on his tenant. Being the search guy I am, I suggested using the search API to do this.

Friday, April 10, 2015

Improving contextual Search in SharePoint Online / 2013

In April 2014 my Puzzlepart colleague Tarjei “The strongest man in SharePoint” Ormest√łyl had a post about how to configure search settings for a site to redirect scope searches over to your search center instead of osssearchresults.aspx. (This would be the “search in this site” search box you find in sites.)
In my recent project we have implemented the same logic as we want scope searches in SharePoint 2010 to be sent over to the new 2013 farm.

I have improved on Tarjei’s solution with the following points:
  • Display title of the site instead of just the URL (or list title as we support 2010 redirects to 2013 search)
  • Implement as a generic script to be added anywhere on the page – preferably in the control template, but for this post I’ll do it as a script web part.
If you look at the code I’m using a neat trick to get the DataProvider for the page and also hook in my logic after the results are ready the first time to fire off my custom scope hint code.

// Get a reference to the DataProvider for the page
var dp = Srch.ScriptApplicationManager.get_current().queryGroups.Default.dataProvider;
// Add event to be called after results are ready

Sunday, April 5, 2015

Why content types are still awesome and useful–despite what the cool guys says

This post is about explaining why you don’t need to be concerned about custom web template id’s in search and how to maintain metadata for a site (root web or sub web). In this new world of SharePoint Online we’re only using built-in web templates and derivatives of them right?

A lot of search queries use the contentclass:sts_site webtemplate:templatename construct to limit results only to root sites of a special site type (or sts_web for sub-sites). Living in SharePoint Online most sites will build of a blank or team site, and using the new provisioning engine from Office PnP, this becomes an issue for many. You can use the engine to save a template definition xml file, and create new ones off it, but how do you distinguish sites from one another?