1

I've been working with JSLink customizations for a couple different Custom Lists we have and they've been working fine when on a page by themselves. Recently I needed to include multiple Custom Views (each with their own JSLink) on a single page and I ran into the issues described in multiple posts here along with http://therelentlessfrontend.com/2014/05/01/having-multiple-jslink-based-webparts-on-the-same-page-overrides-all-the-other-templates-in-sp-2013/

I've implemented the fix found at http://www.myfatblog.co.uk/index.php/2013/09/listview-web-part-issues-with-jslink-and-display-templates-a-solution/ but it completely breaks my JSLink customizations when the BaseViewID is anything but 1. When the code changes it to 99, it won't render properly. If it is set to 1 it renders how it should but then it applies to all custom views on the page.

Here's the View portion of my Custom View:

<View Name="{48B09346-0798-4FE8-8081-B60C68751EB5}" MobileView="TRUE" Type="HTML" DisplayName="LargeButtons" Url="/Lists/LaunchPad Groups/LargeButtons.aspx" Level="1" BaseViewID="1" ContentTypeID="0x" ImageUrl="/_layouts/15/images/generic.png?rev=23" ><Query><OrderBy><FieldRef Name="Group_x0020_Sequence"/></OrderBy></Query><ViewFields><FieldRef Name="LinkTitle"/><FieldRef Name="LaunchPad_URL"/><FieldRef Name="Group_x0020_Sequence"/></ViewFields><RowLimit Paged="TRUE">30</RowLimit><Aggregations Value="Off"/><JSLink>~site/CommonJavascript/LaunchPadHeader_LargeButtons.js</JSLink><XslLink Default="TRUE">main.xsl</XslLink><Toolbar Type="Standard"/></View></XmlDefinition>

Here's the JSLink I'm trying to use:

RegisterModuleInit("~sitecollection/CommonJavascript/LaunchPadHeader_LargeButtons.js", LargeButtonView); // CSR-override for MDS enabled site
LargeButtonView(); //CSR-override for MDS disabled site (because we need to call the entry point function in this case whereas it is not needed for anonymous functions)

function LargeButtonView() {
    // Initialize the variable that stores the objects.
    var overrideCtx = {};
    overrideCtx.Templates = {};

    // Assign functions or plain html strings to the templateset objects:
    // header, footer and item.
    overrideCtx.Templates.Header = customHeader;

    // This template is assigned to the CustomItem function.
    overrideCtx.Templates.Item = customItem;
    //overrideCtx.Templates.Footer = PagingFooter;
    overrideCtx.Templates.Footer = "</div>";

    // Set the template to the:
    //  Custom list definition ID
    //  Base view ID
    overrideCtx.BaseViewID = 1;
    //overrideCtx.ListTemplateType = 10057;
    overrideCtx.ListTemplateType = 100;

    ExecuteOrDelayUntilScriptLoaded(function(){

    //Take a copy of the existing Microsoft Definition of RenderListView
    var oldRenderListView = RenderListView;

    //Now redefine RenderListView with our override
    RenderListView = function(ctx,webPartID)
    {
        //Check the context of the currently rendering List view
        if (ctx.wpq == 'WPQ2') // LaunchPad Groups
        {   ctx.BaseViewID = 99;    }
        else if (ctx.wpq == 'WPQ4') //LaunchPad
        {   ctx.BaseViewID = 98;    }

        //now call the original RenderListView
        oldRenderListView(ctx,webPartID);
    }

},"ClientTemplates.js");

    // Assign a function to handle the
    // PreRender and PostRender events
    //overrideCtx.OnPreRender = preRenderHandler;
    //overrideCtx.OnPostRender = postRenderHandler;

    // Register the template overrides.
    SPClientTemplates.TemplateManager.RegisterTemplateOverrides(overrideCtx);
};

I'm having trouble figuring out what it takes to be able to use a BaseViewID that is not equal to 1 for my Custom Lists. Can someone give me any insight into what I am missing?

Thanks,

Josh

joshmikow
  • 51
  • 1
  • 3
  • 5
  • There are couple of ways. See my answer (comparing view id) and the selected answer for an alternative. http://sharepoint.stackexchange.com/questions/97410/jslink-for-multiple-list-views/97419#97419 – Aveenav Sep 02 '14 at 20:12
  • I reviewed your solution and the selected answer before I posted. It seems like my custom JSLink will only render properly if the BaseViewID=1 for some reason. Also, my situation differs slightly because I'm using 1 page with 2 different views. Each view is from a different source list. – joshmikow Sep 03 '14 at 00:00
  • Higher BaseViewID should work. If you created your list using visual studio then list template id would differ. After applying the JSLink to the webpart, attach it to a debugger and check values, you'll probably get some hint from there. – Aveenav Sep 04 '14 at 14:21
  • I created my list using the web interface and using the "Custom List" app to add it to my site. I created a custom view based on the default All Items view to apply the JSLink to and in its definition it shows "BaseViewID=1". Would I need to change the BaseViewID of the View definition? If so, does the BaseViewID have to match the JSLink file? – joshmikow Sep 04 '14 at 15:29
  • See the answer below: ListOne and ListTwo are custom lists. There are two different views for ListOne. Hope this helps. – Aveenav Sep 04 '14 at 17:51

2 Answers2

4

Note: ctx.view id can be retrieved when you add webparts to the page

// Register Namespace TestListViewJSLink.js
window.CustomListViewOne = window.CustomListViewOne || {};
window.CustomListViewOne.Events = {
    customItemHtml: function (ctx) {
        var EventsHtml =  "<div class='items'>"
            EventsHtml += "  <p class='itemTitle'>" + ctx.CurrentItem.Title + "</p>"
            EventsHtml += "</div>";
        return EventsHtml;
    }
};

RegisterModuleInit("/_catalogs/masterpage/TestListViewJSLink.js", RegisterTestOneListView); // CSR-override for MDS enabled site RegisterTestOneListView(); //CSR-override for MDS disabled site

function RegisterTestOneListView() {

if (typeof SPClientTemplates === 'undefined' || SPClientTemplates === null)
    return;

var overrideCtx = {};
overrideCtx.Templates = {};

//  Assign functions or plain html strings to the templateset objects:
//  header, footer and item.
overrideCtx.Templates.Header = &quot;&lt;div class='headerOne'&gt;&lt;h3&gt;Header One&lt;/h3&gt;&quot;;
overrideCtx.Templates.Footer = &quot;&lt;/div&gt;&quot;;

// This template is assigned to the CustomItem function.
overrideCtx.Templates.Item = window.CustomListViewOne.Events.customItemHtml;
overrideCtx.BaseViewID = 99;
overrideCtx.ListTemplateType = 100;


// Now override the RenderListView once the ClientTemplates.JS has been called
ExecuteOrDelayUntilScriptLoaded(function () {

    //Take a copy of the existing Microsoft Definition of RenderListView
    var oldRenderListView = RenderListView;

    //Now redefine RenderListView with our override
    RenderListView = function (ctx, webPartID) {
        //Check the context of the currently rendering List view
        if (ctx.ListTitle == &quot;ListOne&quot;) {
            //Override the BaseViewID if it's the one we want.
            window.console &amp;&amp; console.log('List is: ListOne');
            if (ctx.view === &quot;{195710EF-2BD1-4203-9C57-B4FFF6B58675}&quot;) {
                //Override the BaseViewID if it's the one we want.
                ctx.BaseViewID = 99;
                window.console &amp;&amp; console.log('Set BaseViewID: 99 ' + ctx.view);
            }
        }

        //now call the original RenderListView with the updated ctx object if applicable
        oldRenderListView(ctx, webPartID);
    }

}, &quot;ClientTemplates.js&quot;);

// Register the template overrides.
SPClientTemplates.TemplateManager.RegisterTemplateOverrides(overrideCtx);

}

TestListViewTwoJSLink.js

// Register Namespace
window.CustomListViewTwo = window.CustomListViewTwo || {};
window.CustomListViewTwo.Events = {
    customItemHtml: function (ctx) {
        var EventsHtml =  "<div class='items'>"
            EventsHtml += "  <p class='itemTitle'><b>" + ctx.CurrentItem.Title + "</b></p>"
            EventsHtml += "</div>";
        return EventsHtml;
    }
};

RegisterModuleInit("/_catalogs/masterpage/TestListViewTwoJSLink.js", RegisterTestOneListView2); // CSR-override for MDS enabled site RegisterTestOneListView2(); //CSR-override for MDS disabled site

function RegisterTestOneListView2() {

if (typeof SPClientTemplates === 'undefined' || SPClientTemplates === null)
    return;

var overrideCtx = {};
overrideCtx.Templates = {};

//  Assign functions or plain html strings to the templateset objects:
//  header, footer and item.
overrideCtx.Templates.Header = &quot;&lt;div class='headerOne'&gt;&lt;h3&gt;Header One View Two&lt;/h3&gt;&quot;;
overrideCtx.Templates.Footer = &quot;&lt;/div&gt;&quot;;

// This template is assigned to the CustomItem function.
overrideCtx.Templates.Item = window.CustomListViewTwo.Events.customItemHtml;
overrideCtx.BaseViewID = 94;
overrideCtx.ListTemplateType = 100;


// Now override the RenderListView once the ClientTemplates.JS has been called
ExecuteOrDelayUntilScriptLoaded(function () {

    //Take a copy of the existing Microsoft Definition of RenderListView
    var oldRenderListView = RenderListView;

    //Now redefine RenderListView with our override
    RenderListView = function (ctx, webPartID) {
        //Check the context of the currently rendering List view
        if (ctx.ListTitle == &quot;ListOne&quot;) {
            //Override the BaseViewID if it's the one we want.
            window.console &amp;&amp; console.log('List is: Test One');

            if (ctx.view === &quot;{626CD2E7-451D-4A5B-8305-8C08E051BDF5}&quot;) {
                //Override the BaseViewID if it's the one we want.
                ctx.BaseViewID = 94;
                window.console &amp;&amp; console.log('Set BaseViewID: 94 ' + ctx.view);
            }
        }

        //now call the original RenderListView with the updated ctx object if applicable
        oldRenderListView(ctx, webPartID);
    }

}, &quot;ClientTemplates.js&quot;);

// Register the template overrides.
SPClientTemplates.TemplateManager.RegisterTemplateOverrides(overrideCtx);

}

Output: enter image description here

Aveenav
  • 4,199
  • 1
  • 14
  • 13
2

I found a simple solution. You just have to add a conditional in your custom render function of the JSLink file. You can use the property that your logic requires. For example, ctx.wpq, ctx.listName, etc.

function customRender(ctx) {
    if (ctx.listName === "{C645375E-A485-4B59-9C95-AAB6DFDF5740}") {
        // Your logic ... 
        var itemID = ctx.CurrentItem.ID;
        var itemTitle = ctx.CurrentItem.Title;
        // More logic ...        
    }
    else
        return RenderItemTemplate(ctx);
}