Custom list view by using the “JS Link” property.

Customizing a list view could be done by using XSLT in previous version of SharePoint. In SharePoint 2013 this van be done by using the “JS Link” functionality. The “JS Link” functionality is included in list view web parts of SharePoint.

You can use this property for adding specific JavaScript files. You can add 1 or multiple when you want to add multiple you will have to separate them using the “|”  symbol. On the internet you can find a lot of articles on how to use the “JS Link” functionality. Normally the “JS Links”  functionality is used to adjust the rendering of a specific field type in my scenario I had to change the complete list view.

In this article I will show you how to define a custom list view using the “JS Link” functionality according to a specific scenario: On project sites we want to follow the status of site migrations (for example SharePoint sites). The status of these migrations can be saved within SharePoint lists:

clip_image002

In this list you will need to have two fields:

  • Title: The title of the site that needs to be migrated.
  • Status: The status of the migration. In this example we will have three statuses: “Not started”, “In progress” en “Done”.

Using this list we can manage the status of the migrations. At this moment we only have to add functionality to see the migration status of all sites in one view without the use of a farm solution.

clip_image004

In the above image you can see the same list but a altered view with the use of “JS LInk”. This view shows a doughnut view with three different colours. So how can we achieve this without creating a full trust solution.

First off all we searched for a JavaScript library to be able to create a doughnut chart. We choose the following library:

Now that we have a library we can start writing a JavaScript file that we need to load within the “JS Link” property. Within the JavaScript file we first off all register a namespace to not get in the way of other JavaScript code besides that we also define a view variables that we can  use within the namespace.

var migrationStatus = migrationStatus || {};

migrationStatus.InProgressString = 'In progress';
migrationStatus.DoneString = 'Done';
migrationStatus.NotStartedString = 'Not started'; 
migrationStatus.ListName = 'Migration';
migrationStatus.ItemsDone = 0;
migrationStatus.ItemsInProgress = 0;
migrationStatus.ItemsNotStarted = 0;

To be able to define template you will need to define specific overrides. These overrides can be defined by using the “RegisterTemplateOverrides” method on the “SPClientTemplates.TemplateManager” object. This method needs one object that defines what needs to be overridden. We will define this within the method: “CustomizeViewRendering”.

// Create a function for customizing the view rendering of the list
migrationStatus.CustomizeViewRendering = function () {
    var migrationStatusContext = {};
    migrationStatusContext.Templates = {};
    migrationStatusContext.Templates.View = migrationStatus.RenderMigrationViewBodyTemplate;
    migrationStatusContext.OnPostRender = migrationStatus.OnMigrationViewPostRender;
    SPClientTemplates.TemplateManager.RegisterTemplateOverrides(migrationStatusContext);
};

In the “migrationStatusContext” object needs to be defined which rendering methods needs to be overridden. As you can see in the above snippet the “OnPostRender” and the “Templates.View” will be overridden. These methods we will discuss in the upcoming paragraphs.

Note:When you override the rendering methods, this will be for every list view on a page. If you want to override the view rendering of one specific list you will have to build in a check if you are performing the action on the correct list.

migrationStatus.RenderMigrationViewBodyTemplate = function (ctx) {
    if (ctx.Templates.Body == '') {
        return RenderViewTemplate(ctx);
    }

    if (ctx.ListTitle == migrationStatus.ListName) {
        var listData = ctx.ListData;

        for (var idx in listData.Row) {
            var listItem = listData.Row[idx];

            if (listItem.Status == migrationStatus.InProgressString) {
                migrationStatus.ItemsInProgress++;
            } else if (listItem.Status == migrationStatus.NotStartedString) {
                migrationStatus.ItemsNotStarted++;
            } else if (listItem.Status == migrationStatus.DoneString) {
                migrationStatus.ItemsDone++;
            }
        }

        var htmlOutput = [];
        htmlOutput.push('<div id="listData"><a href="' + ctx.listUrlDir + '"> View this list</a></div>');
        htmlOutput.push('<div id="migrationstatusView" style="height:400px;width:400px;margin-top:10px;float:left;margin-bottom:10px;display:block;">');
        htmlOutput.push('<canvas id="myChart" width="250" height="250"></canvas>');
        htmlOutput.push('<div id="chartLegend" style="width:150px;float:right;" />');
        htmlOutput.push('</div>');
        

        var retVal = htmlOutput.join('');
        return retVal;
    }
    else {
        return RenderViewTemplate(ctx);
    }
}

The “migrationStatus.RenderMigrationViewBodyTemplate” function needs to be used to adjust the view. This method also receives the context (ctx) object in which all information regarding the context (in this example list) is saved. From this context we can retrieve all of the list data.

But first we will have to check if the body of the template isn’t empty. When it is empty we will have to call the default renderer. After that we can check if the list we are performing the actions for is our migration list: “ctx.ListTitle == migrationStatus.ListName” if this isn’t the case we also call the default rendering function:

return RenderViewTemplate(ctx);

When this list is our list we count all of the statuses and place them in the specific variables. When all this is done we write out the HTML we need for the rendering of the graph and legend and we return this.

De “PostRender” function will be called as last. In this function the graph will be loaded with the correct data and besides that we will also load the legend of the graph.

migrationStatus.OnMigrationViewPostRender = function (ctx) {
    if (ctx.ListTitle == migrationStatus.ListName) {

        var pieData = [
        {
            value: migrationStatus.ItemsNotStarted,
            color: "#F7464A",
            highlight: "#FF5A5E",
            label: migrationStatus.NotStartedString
        },
        {
            value: migrationStatus.ItemsDone,
            color: "#46BFBD",
            highlight: "#5AD3D1",
            label: migrationStatus.DoneString
        },
        {
            value: migrationStatus.ItemsInProgress,
            color: "#FDB45C",
            highlight: "#FFC870",
            label: migrationStatus.InProgressString
        }];
        
        var options = {
            //Boolean - Whether we animate the rotation of the Doughnut
            animateRotate: true,
            //String - A legend template
            legendTemplate: '<ul style="list-style-type:none;" class="<%=name.toLowerCase()%>-legend"><% for (var i=0; i<segments.length; i++){%><li><span style="width:20px;height:10px;display:block;background-color:<%=segments[i].fillColor%>"></span><%if(segments[i].label){%><%=segments[i].label%><%}%></li><%}%></ul>'
        };

        //get the chart element and setup the doughnut chart
        var ctxChart = document.getElementById("myChart").getContext("2d");
        var myPie = new Chart(ctxChart).Doughnut(pieData, options);

        //generate the legend html
        var legend = document.getElementById("chartLegend");
        legend.innerHTML = myPie.generateLegend();
    }
};

In the “PostRender” function we also need to check if we are performing the action for the correct list.

The final thing we need to adjust to the JavaScript file is adding the following line:

migrationStatus.CustomizeViewRendering();

This line of code will be called on the moment the file is loaded and by calling this function is will make sure that the overrides for the list views will be registered.

Know that the files are ready we only need to specify the files in the “JS Link” property of the list view.

clip_image006

In the “JS Link” we have specified the following value:

/siteassets/Migration/Chart.js|/siteassets/Migration/MigrationStatus.js
  • /siteassets/Migration/Chart.js: JavaScript library for the generation of graphs.
  • /siteassets/Migration/MigrationStatus.js: JavaScript file for the list view.

 

GitHub Repository:

https://github.com/MaikvanderGaag/MigrationStatus

Video from Webucator with a complete outline of my blog post:

 

Related Posts

Google Maps Display Template – SharePoint 2013 – Part 2 As described in my previous post we will be creating a display template for Google maps. When you did not have the change to read part 1 you can do th...
Google Maps Display Template – SharePoint 2013 – Part 1 As the most of you will know by now is that SharePoint 2013 has a new web part called the “Content Search” web part. This web part display’s search re...

41 comments

  • Thanks for the tutorial. It was very helpful. I have this implemented for a site and it has the same list used twice on one page. The problem is since it looks for list title, it is trying to run this code for both instances of the list view. I only have the JSlink active on the one view, but it is still treating both instances the same. Any ideas?

  • I got the to work but my animated donut is all “Green” Do I need to do something in the code to get it to display Red, and Yellow as well? Thanks!

  • I give up. I have spent the past two days trying to figure out why this tutorial is not working for me. When my “chart” renders it only gives me the “Done” status from my “Migration” list. I am to much of “newbie” at JSLink to know how to debug this situation. I need some help please. Do I need to change the code in ‘Chart.js’. When I open up the code in debugger the only clues I have is it says “pieData”, “options”, “ctxChart”, “myPie” and “legend” in the “Watches” window are all “undefined” As I said, I have followed the video and documentation and am using the JavaScript code and Chart.js code. Please help me understand what I need to “modify” in each code to make this work. Any help in understanding why this is not working would be greatly appreciated for this “newbie”. I am at a loss…. Thanks!!

    • Hi Dave, make sure the string values are exactly the same as the values in your status column. Maybe you have a space in front or at the end of the status values.

      • Maik, that did the trick!!! In the code above ‘In progress’ needs to be ‘In Progress’ and ‘Not started’ needs to be “Not Started’ in order to match up with what SharePoint names them in the “Status” column. Thanks!!

    • Did you fixed this code, I’m trying to apply it but not luck.

  • I followed your example and recreated MigrationStatus.js , Migration list, and download Chart.js on my SharePoint site but I am not able to get it to work. Is there a location where I can download MigrationStatus code to ensure I do not have typos?

  • Hi,

    i can only see the View this list url on the page. i tried debugging the page but couldnt see any error or anything else unusual. Everything is same including column names except for the ListName. Can you please suggest what has gone wrong.

    Thanks,

  • Same thing here Mubashshira.. any other information ?

  • Hi, I’ve been struggling with this code for a couple of days, finally it is running but not show anything, debuggin the code i found this: ReferenceError: Chart is not defined at Array.migrationStatus.OnMigrationViewPostRender, could you please help me with this issue.

    Regards

    • Hi Efrain,

      Problems can occur because of different things other versions of SharePoint or JS versions. The version we used is explained on the site. Maybe you could try the Fix Dave applied and is described in the Comments.

  • This looks like a good solution, pity it just doesn’t work on my page. Looked at the developer tool to see if the scripts load, but they don’t even load. I’m really not sure what the problem could be. I also tried reference the Chart.js file from their instead, that didn’t work either. Please help anyone

    • Hi Vusi,

      First things first, you will have to make the script load first. Is the file checked-in and referenced correctly?

      • Hi Maik

        the referencing to the js files was correct, but it would seem the js link property just doesn’t work on me, at all. I put the scripts in script editor webparts and there was something even the it was a blank screen with just page numbers. I put some alerts for testing everything seems cool. I’m really not sure what could be wrong. Please assist.

        • Hi Vusi,

          Where did you save the JS file for JS Link? Did you try the SiteAssets library or Style Library? Also make sure that all properties defined are correct (Case sensitive and all).
          What is the output on your page at this moment.

          • I have a Document Library where I save my scripts. Currently it shows a blank page with the text “View this list” and paging numbers at the bottom. That’s only when I use the script editor webpart instead of the js link property. js link property doesn’t even load the scripts. Is it maybe my sharepoint version? I’m on SharePoint 2013 standard on premise.

          • I’m really convinced now that location of the file is really a problem but I really don’t where I should put the files. I tried masterpage gallery, site assets library and site script library and still no luck. But based on the responses I see that location of the file is very important.

        • Try a different location for your scripts, a site assets library and if that doesn’t work the style library. I can remember that I hade problems using a document library.

          • I have no luck still. When I use script editor I see it loads blank, the chart is just not loading. I just wonder if there’s more stuff to do when downloading that Chart.js or it’s plug and play??

          • Hi Vusi, I would stop using the script editor and place the script files in a siteassets library. When loaded in the correct order everything would have to work correctly, if you also used the right parameters.

          • Hi Maik

            I have managed to get the scripts to load, it needed to be under master page galleries and make sure you choose javascript display template in the properties of the file you uploading. But the charts are still not showing, and no error. I just a blank space where the chart should be displaying. I checked the field names, it is correct. what else is missing??

          • Hi Vusi,

            That’s great, you will have to try the Internet explorer debugger and make sure that every thing is configured correctly according to your data in the list and the saved values.

  • Hi where can I download MigrationStatus.js?

    • You can’t you will have to do a little bit of work by copying the source code.

        • Thank you very much. I have copied the file and was able to execute it. I can test “RenderMigrationViewBodyTemplate” function is working. But unable to execute – “OnMigrationViewPostRender”. I was not able to add htmlOutput.push to see if I’m in that PostRender method.

          I copied Chart.js from CDN, not worked; I’ve downloaded multiple files and uploaded to my SharePoint, not worked. I tried to point to direct CDN link and not worked.

          I’m not able to instantiate the Chart object. Do you have tips on how to debug any further? Or can you do a little consulting to configure it? Please

          Can you give me a pointer?

          • Hi Ankit,

            What is the error when you open the F12 Developer tools in Edge or Internet Explorer?

          • Hi Ankit

            I had similar problems. But after sometime struggling to get the scripts to even load on the page. I bumped into the following link: https://www.dynamics101.com/jslink-sharepoint-2013-get-started/ , which explained exactly where to load your js files. You need to load them on the masterpage gallery as that provides with so many properties on file upload. You need to tick properties like your Content Type(Javascript content type, in this case), Target control type(View in this case), Target scope(which is the url to the page you want this to work on) and Standalone(Override in this case). Once that is done, you will be able to load your scripts on to the page.

            I hope this helps.

          • Hi Vusi,

            Thank you for the reply. It is still a strange issue, when I made the script I have tested it in multiple libraries and never had any issues. Hope this helps Ankit.

  • How can we implement this in sharepoint online, because there we can not give JS link in the web part?

  • Its difficult to acquire knowledgeable folks during this topic,
    but the trutyh is could be seen as guess what happens you are referring to!
    Thanks

  • Showing error for me – “Uncaught TypeError: migrationStatus.CustomizeFieldRendering is not a function”

  • Still getting the View this List error on SP 2013 environment. I’m correctly referencing the file using JSLink and have placed all files in the master gallery folder. Any ideas?

Leave a Reply

Your email address will not be published. Required fields are marked *