Having multiple JSLink based webparts on the same page, overrides all the other templates in SP 2013


Scenario:

Create a dashboard page in SP 2013, displaying just 3 lists in 3 different views using Js Link capability. The 3 lists are:

  1. Accordion: A list containing title and description which will be displayed on the dashboard with an accordion functionality with title being the accordion item heading and description being the accordion item body.
    Image
  2. Menu: A list containing entries that can be used to construct a mega menu or a navigation menu.
    Image
  3. Alert: A list containing entries whose Body contents are lengthy and hence have to be trimmed down and ellipsis (…) added to the lengthy ones
    Image

The dashboard page was created and all the 3 list view webparts were added to it. All of them were given 3 different JsLink with different namespaces and method names. Each js had their template methods that rendered the list in the desired views and functionalities. ex. the accordion template method just returned “<h2>{Title}</h2><p>{Description}</p>” and an OnPostRender jQuery script to toggle them on <h2> click.

Issue:

Loaded the Alert list first on the fresh page–> No issue; trimming the body content worked perfectly

Image

Loaded the Accordion list next –> No issue; slide up and down of the accordion worked perfectly
Image

Loaded the Menu list next –> Boom! The accordion lost its Js Link functionality and started behaving like the menu displaying items using the template defined for the Menu list.

Image

Attached below are the 3 JsLink files used:

AlertsAccordion | Menu

Feel free to test it out…

If the JS Links had different namespaces & methods, why would it overwrite all the other templates on the same page? Could it be by design? By changing the BaseViewID, i could get the Accordion working but the menu then started taking the accordions template behavior…:(

Finally, I ended up having a single Js Link file (added as JS Link to all the webparts on the page) having the same template method, but internally it loaded different templates for each webpart by doing an <if> condition check for the List Name.
ex. if (ctx.ListName==’Accordion’) return “<h2>{Title}</h2>…”; if (ctx.ListName==’Menu’) return ‘<ul><li>{Tite}</li></ul>’; etc…

But somehow you will feel something is not right when you code it. Having a bulky js method with If-else or switch-cases…:(

Solution:

Paul Hunt (@Cimares) has the solution for this scenario wonderfully detailed out here.This solution works and you can do an IF condition check to load the templates corresponding to each webpart accordingly.

I still wish if i could use independent JS Link files for all the webparts on the dashboard…:(…But, all in all JSLink is wonderful and I am happy to see MS taking the client side route and would love to support them in this direction…:)

Feel free to post your comments or possible alternatives or solutions.

  1. The javascript files are no longer available. Can you please post them again?

    Reply

  2. Hi blogger, i must say you have high quality posts here.
    Your page can go viral. You need initial
    traffic boost only. How to get it? Search for; Mertiso’s tips go
    viral

    Reply

  3. Same page (Using Jslink)

    Reply

  4. Hi aackose,

    How to display Three different Views For Same List ?

    Reply

  5. Hi Aackose,

    Ok I think you’ll find the problem is that you’ve only set a new BaseViewID in one of your three JSLink files. You’ll need to do it in all three, and then override the Render method in just one of them, adding the logic for each into this one..

    Also, I’ve changed the method I use now, and rather than use the listname, I use the WPQ id instead.

    The new render method should look like this:-

    var OldRenderListView = RenderListView;
    RenderListView = function(ctx,webPartID)
    {
        //Check using the F12 developer toolbar, which WPQ number is required for the webpart
        if (ctx.wpq == 'WPQ2')
        {
            ctx.BaseViewID = 99;
        }
        else if (ctx.wpq == 'WPQ3')
        {
            ctx.BaseViewID = 98;
        }
        else if (ctx.wpq == 'WPQ4')
        {
            ctx.BaseViewID = 97;
        }
    
        OldRenderListView(ctx,webPartID)
    }
    

    And if you want an easy way of finding out the WPQ id of each webpart, just add my new Debug template onto a single webpart… It’s in the new #SPCSR library..

    https://github.com/SPCSR/DisplayTemplates/tree/master/JavaScript%20Display%20Templates%20(JSLink)/Debugging%20ListView%20Template

    Hope this helps.

    Paul.

    Reply

    1. Thanks Paul,

      Works like a charm. And the CSR library is very useful.

      Reply

Feel free to leave a reply here...