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

  • There are couple of ways. See my answer (comparing view id) and the selected answer for an alternative. sharepoint.stackexchange.com/questions/97410/… – Aveenav Sep 2 '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 3 '14 at 0: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 4 '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 4 '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 4 '14 at 17:51
3

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 = "<div class='headerOne'><h3>Header One</h3>";
    overrideCtx.Templates.Footer = "</div>";

    // 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 == "ListOne") {
                //Override the BaseViewID if it's the one we want.
                window.console && console.log('List is: ListOne');
                if (ctx.view === "{195710EF-2BD1-4203-9C57-B4FFF6B58675}") {
                    //Override the BaseViewID if it's the one we want.
                    ctx.BaseViewID = 99;
                    window.console && console.log('Set BaseViewID: 99 ' + ctx.view);
                }
            }

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

    }, "ClientTemplates.js");

    // 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 = "<div class='headerOne'><h3>Header One View Two</h3>";
    overrideCtx.Templates.Footer = "</div>";

    // 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 == "ListOne") {
                //Override the BaseViewID if it's the one we want.
                window.console && console.log('List is: Test One');

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

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

    }, "ClientTemplates.js");

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

Output: enter image description here

1

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);
}

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.