2

This is my problem and please let me know if I am approaching it incorrectly. I have a list called "document classes" that holds information such as the retention and revision periods for documents, whether those fields are requried for a particular class, and which department can use those classes. The key piece of information I need from this list is the retentionAmberDays and retentionRedDays for each class as this defines how long before the date a traffic light warning should be displayed.

I want to be able to query all documents in my site collection and highlight documents that have passed these dates, but in order to do this I need to have access to the data values. To do this in other scenarios, I would load the data in an array first via query and then check the array for each item to get the particular value I need.

I think that Search Display Templates are my best bet for building this functionality but the problem is that calling javascript in the tag happens asynchronously and the files are not always loaded before the item rendering logic is processed.

So, how can I load all my javascript files, and run some functions BEFORE the search item rendering logic begins so that the rendering logic can then use that data?

I hope that explanation made sense, reading it back now it seems confusing :-)

Thanks

  • You could alter your javascript so that it executes after the async search job completes. Would that work? – tyshock Feb 4 '14 at 15:36
  • Hi tyshock, thanks for the response. When each earch item is rendered, I want to reference the data pulled through so i need the javacript files already loaded. Also I want to make use of a javascript date library to manipulate the dates during rendering so for that I also need the files loaded before rendering starts – user23429 Feb 4 '14 at 21:12
  • 1
    You can run your javascript whenever you would like. Also, this javascript, using jQuery for convenience, can alter the existing data on the page however you would like. It sounds to me like you just need to setup the javascript so that it runs AFTER the ajax calls are completed and the search data is on the page. – tyshock Feb 4 '14 at 21:17
  • Hi tyshock, yes I considered this approach but have not gone there as it seems more complicated to me and I didn't want to have to worry about the user seeing the display change in front of them, although i am aware I could work around this. I assumed that there would be a method of loading the javascript in advance but if thats not the case I will need to take the approach you describe. – user23429 Feb 4 '14 at 21:27
  • Depending on how you wire it up, the user may not notice the rendering 'flicker'. What I would do is observer some dom element with jQuery that you know changes in some way once the data is loaded. As soon as that element changes, launch your logic which will format the data as you would like. See stackoverflow.com/a/5154897/16448 for an example on watching an element for changes. – tyshock Feb 4 '14 at 21:37
1

When you create your custom Item html file and publish it, it auto generates the javascript file for you (you'll need publishing feature for this). In your html file load your javascript files inside HEAD section.

Within the generated JS file, look for RegisterModuleInit function which calls another function 'RegisterTemplate_...(guid)"

Within the function 'RegisterTemplate_...(guid)' you can use either jquery's $.getScript to load your js files dynamically and then within the callback continue with search registerTemplate logic.

    //$.getScript alternative to include cache
    jQuery.getCachedScript = function (url, callback) {
        jQuery.ajax({
            dataType: "script",
            cache: true,
            url: url,
            success: callback
        });
    };

    function RegisterTemplate_dba72a49893c41c59faa7e4790ca87c5() {

        ExecuteOrDelayUntilScriptLoaded(ClientObjectCode, "sp.js");

        function ClientObjectCode() {

            jQuery.getCachedScript(_spPageContextInfo.webAbsoluteUrl + "/_layouts/15/mycustomscript.js", function () {
                window.console && console.log("mycustomscript loaded");
                // Now run original  RegisterTemplate_dba72a49893c41c59faa7e4790ca87c5() content/logic
                if ("undefined" != typeof (Srch) && "undefined" != typeof (Srch.U) && typeof (Srch.U.registerRenderTemplateByName) == "function") {
                    Srch.U.registerRenderTemplateByName("MyCustom_Item_Site", DisplayTemplate_dba72a49893c41c59faa7e4790ca87c5);
                }

                if ("undefined" != typeof (Srch) && "undefined" != typeof (Srch.U) && typeof (Srch.U.registerRenderTemplateByName) == "function") {
                    Srch.U.registerRenderTemplateByName("~sitecollection\u002f_catalogs\u002fmasterpage\u002fDisplay Templates\u002fSearch\u002fMyCustom_Item_Site.js", DisplayTemplate_dba72a49893c41c59faa7e4790ca87c5);
                }
            });
        }
    }

There's also a OnPreRender function used for overriding context of JSLink. Something similar could be used here within Display Templates too. You can explore on that.

  • Hi Aveenav, thanks for your reply. In my reading everyone was saying "don't touch" regarding the javascript file that SP generates for the display template so I have done nothing more than have a peek so far. Do I risk breaking the display template if I modify this file? – user23429 Feb 4 '14 at 21:18
  • Take a look at: fiechter.eu/blog/Lists/Posts/Post.aspx?ID=29&mobile=0 , this is what I was talking about, the post shows how to use custom functions on PostRender but you can also override PreRender function to inject your own logic. You would only need to edit the HTML of the display template. – Aveenav Mar 4 '14 at 16:56
0

I recommend against editing js directly unless you really know what you are doing. Edit html file and SPD will generate a js for you.

  1. You need to have two templates = Control + Item.
  2. In you control templates you load your JS etc and core html markup/layout
  3. In item template you render your item ( your js already loaded via control )
  4. In controls template OnPostRender you can process your items rendered on the page
  5. Finally show your hidden div with items to user.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.