Blog

Using JSLink with SharePoint Lists to Render Custom WebParts

Using JSLink with SharePoint Lists to Render Custom WebParts

Say you have a basic list in SharePoint and want to display the list data on your SharePoint page. A typical list that looks like a grid can be pretty dull, so it is common that a company or developer would want to show the list in a way that is not explicitly made available in SharePoint.

Sure, SharePoint lets you filter out items/columns, etc., but it may not look nice as a simple grid, and you want to add some extra functionality. Lists and libraries are great at storing data in SharePoint, but when you add a simple grid view of the data on a page, it leaves you striving for something more visually pleasing.

Believe it or not, with a little coding knowledge, you can write code to override what a list/library WebPart looks like on your SharePoint page! For classic SharePoint pages, we can easily make use of a technology that SharePoint has built in to display virtually whatever you'd like with the data from that WebPart.

This blog will describe how to use JavaScript on your SharePoint page and how to use SharePoint's built-in JSLink technology. It takes a relatively small amount of code for a pretty cool outcome.

Use Case

Say we have a SharePoint list called "Employee Info" that has three columns: Name, Department, and Employee Picture. Rather than the user having to look at the out of the box grid WebPart for the view, we want to show something easier to read and better looking.

For each person, I had an idea to show a bordered box that includes the employee name, picture, and department. We have all of the data that we need, and we need to make what is inside this WebPart look a bit more presentable.

To do this, we are going to write JavaScript code that will automatically be run on the page load when the WebPart is rendering. Before SharePoint renders the view of the list on the page, we will step in and instead give SharePoint something else to render.

As a developer, maybe some of the wordage just used is already getting your wheels turning. You can probably imagine some of the steps we are going to have to take to make this work. On a high level, with our code, we will need to make sure to do the following:

  1. Hook up to/find the SharePoint list that we want to manipulate
    1. Sharepoint's JSlink feature on a list WebPart gives us direct access to the list and the items in it. So your JavaScript code will get passed the elements in the list.
    2. If you want to configure the list WebPart to be a specific view (say, only showing Employees where their "Department" column is equal to "Accounting"), there is no more work you need to do, because the sorting is done by SharePoint in the configuration and doesn't have to be done in the code.
  2. For each of the items in the list, we need to give SharePoint the item that we want to show.
    1. In this case, we're getting all the elements from the list but just displaying them in a visually pleasing way.
      1. In HTML terms, for each employee, we will probably want to render a div, and inside the div, there could be an img tag for the picture and divs for the name and department. We can use CSS to add our custom styles.

We will plan to create a JavaScript file that will interact with the page and overwrite the view of our WebPart. Once we point our WebPart to the code we have written, we'll be good to go!

Now, because we are overriding what is rendered, we are getting rid of the HTML and everything that was there in the first place related to the look of the normal SharePoint WebPart. As a result, we'll have to return our custom content to SharePoint. Below are some of the technologies/languages we'll use.

Our Toolbox

  • SharePoint List
    • This is where our data resides. In our example, we created an "Employees" list in the Site Contents of our SharePoint page
  • List WebPart
    • On our classic SharePoint page, we added a WebPart to display the employee list.
  • JavaScript File
    • This file contains all of our logic. We upload this file to our site's Site Assets folder, copy the URL of it, and add this URL to the JSLink section of our list WebPart's settings pane. Under the miscellaneous section of the settings pane, you will find the JSLink option.
  • HTML
    • We return HTML markup from our JavaScript, which is what the WebPart renders instead of its default HTML.
  • CSS File
    • For when the HTML that we return from the JavaScript is on the page, we can have CSS styles uploaded to SharePoint that will style the new content of the WebPart to our liking.
    • We'll put this CSS File into Site Assets as well.

Alright, enough of the setup, here is what the full JavaScript file for this example looks like. Below, I'll go into detail about certain parts of this JavaScript file.

The function where we're doing almost all of the work is in RenderViewBodyTemplate. I'll explain what's going on here and then go over some of the other important parts of what makes this work:

 /* this is the function that SharePoint normally calls that we are overriding.
    By overriding this function, when SharePoint tries to render our custom webpart,
    it will display whatever we return from this function */
    DMCExample.EmployeeListScript.RenderViewBodyTemplate = function(renderCtx) {
        // renderCtx is the render context, which SharePoint passes to this function

        // the ListData property will have all of the data for this webpart view
        // ListData can be iterated through to get information from each list item
        var listData = renderCtx.ListData;

        // the number of items in the list
        var rowCount = listData.Row.length;
        if (renderCtx.Templates.Body === '') {
            return RenderViewTemplate(renderCtx);
        }

        // the opening div tag for our webpart. We will remember to close it after we have added all of our elements
        // also adding a custom id for this div so we can easily style it with our css
        var EmployeesWebpartHTML = '<div id="EmployeesWebpartDiv">';
        for (var i = 0; i < rowCount; i++) {
            EmployeesWebpartHTML +=
                '<div class="employee-container">' +
                    // this is the internal name of the field on our example list.
                    '<img src="'+listData.Row[i].EmployeePictureLink+'" />' +
                    '<div>' +
                        '<span class="employee-name">'+listData.Row[i].EmployeeName+'</span>' +
                    '</div>' +
                '</div>';
        }
        
        // our closing tag that we needed to remember
        EmployeesWebpartHTML += '</div>';

        return EmployeesWebpartHTML;
    };

As you can see, we are programmatically constructing the HTML, and then returning it, which sends it to SharePoint when it is trying to render the WebPart.

Because we added some classes, we can now easily style these elements with CSS. In the for-loop, we are iterating over the items in the list and inserting them into our HTML.  

The name of the fields is "EmployeePictureLink" and "EmployeeName".

SharePoint's Internal Field Names

Finding Internal Name of List Column

When referencing a column from your SharePoint list in your JavaScript, you're going to want to use the internal name of the column. These internal names are what SharePoint stores the name of the column as in the backend. These internal names are what you'll reference the field as when getting the information.

I'll tell you a straightforward way to get these internal names so you can use them, but here are some common tips/rules for internal names:

  • If your column name is one word, like "Department," SharePoint will store the internal name as "Department."
  • SharePoint changes the name when you have a space in your column name. For example, "Contact Name" will probably be "Contact_x0020_Name" because the text in the middle is how SharePoint stores spaces.
  • To find the internal name of a column, go to your list in SharePoint and then go to List Settings. You can find the List settings by clicking the gear in the top right of the page. Once you're in list settings, scroll to the bottom and click on the name of the column you want the internal name for. In the new page that you are taken to, the field name should be at the end of the URL of that page.

SharePoint URL for contact name

While this is all you'll need for the majority of the functionality, here are some other aspects to make sure that your code works:

DMCExample.EmployeeListScript.Create = function() {
        var viewContext = {};

        viewContext.Templates = {};
        viewContext.Templates.View = DMCExample.HomeLinks.RenderViewBodyTemplate;
        viewContext.OnPreRender = DMCExample.HomeLinks.OnViewPreRender;
        viewContext.OnPostRender = DMCExample.HomeLinks.OnViewPostRender;
        viewContext.BaseViewID = 100; //Note: This is the BaseViewID we'll set when the renderlistview is called.

        // 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
                // This long string of numbers and letters is the GUID of the list
                if (
                    ctx.listName &&
                    ctx.listName.toUpperCase() ===
                        '{BB9516A6-4E02-4048-8D66-1B2D2109D096}'.toUpperCase()
                ) {
                    var isInEditMode = false;
                    var pageForm = document.forms[MSOWebPartPageFormName];
                    if (pageForm) {
                        if (pageForm.MSOLayout_InDesignMode) {
                            isInEditMode = pageForm.MSOLayout_InDesignMode.value === '1';
                        }
                        if (pageForm._wikiPageMode) {
                            isInEditMode = isInEditMode || pageForm._wikiPageMode.value === 'Edit';
                        }
                    }
                    if (!isInEditMode) {
                        //Override the BaseViewID if it's the one we want.
                        ctx.BaseViewID = 100;
                    }
                }

The BaseViewID we set to 100 is a bit arbitrary. 100 is, more than likely, higher than the number of other WebParts not using this JSLink code on the page. BaseViewID is what links together all of the functions in this JavaScript file. The main thing to note is, if you have another JSLink file, make sure that it has a different BaseViewID. I usually start at 100 and count up.

You may also notice the long string "{BB9516A6-4E02-4048-8D66-1B2D2109D096}". This string is the GUID (unique identifier) of my employee list. JSLink, by nature, runs for every WebPart on the page, even if you only linked it into one WebPart. This check makes sure that we're looking at the WebPart for our employee list.

If that is the case, we will set the BaseViewID on the context object, which matches the initial BaseViewID that we set up, thus linking the functions together and allowing them to work when we call SPClientTemplates.TemplateManager.RegisterTemplateOverrides(viewContext);

Towards the bottom of the JavaScript file, the code reads:

if (!isInEditMode) {
                        //Override the BaseViewID if it's the one we want.
                        ctx.BaseViewID = 100;
                    }
                }

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

        SPClientTemplates.TemplateManager.RegisterTemplateOverrides(viewContext);
    };

    ExecuteOrDelayUntilScriptLoaded(DMCExample.HomeLinks.Create, 'clienttemplates.js');
})();

At the end of our code, we call a function named ExecuteOrDelayUntilScriptLoaded. As you can see, the first parameter we pass into that function is the name of our main function called "Create."

The second parameter is the name of a script. The file that we have in the second parameter is "clienttemplates.js." This built-in SharePoint function means "don't run the object in the first parameter until the second parameter is loaded." Therefore, we don't run our Create function until clienttemplates.js is loaded.

This file, "clienttemplates.js," is the core file that SharePoint loads to allow for client-side rendering. We need this file to load before our code would be able to work.

Now that we have created our code, we are ready to put it all into SharePoint and watch it work!

  • Make sure that your JavaScript file (and CSS file if you have one) are in your Site Assets folder for your SharePoint site.
    • Copy the link to your notepad and replace everything before /SiteAssets with a "~," and then either "site" or "sitecollection". You will put "sitecollection" if your JS file is in the SiteAssets folder of a root site of a site collection, or "site" otherwise. So the link would appear as ~sitecollection/SiteAssets/…
  • On your SharePoint page, edit the page and click on the properties for the WebPart. A pane on the right-hand side of the page should pop up for the WebPart settings. Under the miscellaneous section of those settings, in the JSLink box, place that edited URL.
  • Now the JSLink should be running!

Adding the Style Files

  • In your site settings, under the "Look and Feel" group of options, click "Master Page." If this doesn't show up, you'll need to enable the SharePoint Server Publishing Infrastructure in Site Features.
  • If not activated, go to Site Collection features and activate SharePoint Server Publishing Infrastructure
    • Under there, you can go to the "Alternate CSS" area and post the link to your CSS file in it.
    • Now, the CSS that is in your Site Assets folder should be used when the page loads. For example, if in your JSLink file, one of the divs that you return to the view has a classname of "employee-picture," in your CSS you could reference that class to add your styles!

At this point, with the tools and code provided above, you should be able to move forward and render SharePoint lists on the page to your liking. The sky is the limit with JSLink, and with it, we can turn this easily stored data into beautiful and functional custom WebPart to fit your needs!

Learn more about DMC's SharePoint Consulting Services and Digital Workplace Solutions team. Contact us for your next custom SharePoint project.

Comments

There are currently no comments, be the first to post one.

Post a comment

Name (required)

Email (required)

CAPTCHA image
Enter the code shown above:

Related Blog Posts