JSLink can only be registered on certain list templates. This works well as long as only one web part on a page will be shown. If you added multiple list views of the same list template the template override will affect all web parts and not only the one that has the JSLink File attached to. To avoid this behavior the template override needs to be able somehow to conditional format the output.

Use Case for conditional web part formatting

Let’s say we have a list that shows all the incoming and outgoing money. While the outgoing money has a leading minus sign the incoming money only shows positive values. Now we like to show this list as a summary on the landing page. Additionally, we like to add a second list view on the landing page that shows only incoming money. For a better visualization, we like to show the values of the first web part in a different color. Red for negative values and green values for incoming money.

This makes sense for the first web part, but not for the second because it is filtered to show only positive values.

In Excel this is a pretty easy task to accomplish because all we need to do is to simply format the cells with the conditional formatting. In SharePoint we need to override the field rendering using JSLink.

In SharePoint the default view only shows the values in black.

The default views don’t look that nice because all the “Sum” fields on the page looks black. The only difference is the small minus sign right in front of the actual amount.

On the other hand it does not make sense to clear the list below two because only values that are greater than zero will be shown.

Apply JSLink to highlight positive and negative values

To show the values of the “Sum” field in different colors all that needs to be done is to write a field override. The following code implements such a basic field override.

(function () { var myFormContext = { Templates: { Fields: { Sum:{ View: function(ctx){ // Text value displayed var sumText = ctx.CurrentItem.Sum; // Float value of field var sumValue = ctx.CurrentItem['Sum.']; if(sumValue < 0){ return "<span style='color: red'>"+sumText+"</span>"; } else { return "<span style='color: green'>"+sumText+"</span>"; } } } } }, ListTemplateType: 100 }; SPClientTemplates.TemplateManager.RegisterTemplateOverrides(myFormContext); })();

You might noticed inside the “View” that I worked with two different values. The “sumValue” and the “sumText”.

ctx.CurrentItem.Sum:

This property contains the rendered field value, including the currency sign.

ctx.CurrentItem[‘Sum.’]:

The property “Sum.” needs to be requested using the array notation because the dot has a special meaning in JavaScript.

I added this JSLink override to the first web part only, but the result looks like this.

Not really the expected result. JSLink attached to only one web part affects all the fields that exist on a page. In this case the “Sum” field of the same generic list exists two times on the page and all the instances will be overwritten.

To avoid that the JSLink will be attached to both web parts we need to find a way how to differentiate the web parts.

Bind JSLink to certain Web Parts only

To make the UI changes only available in a single or multiple web part, but not all we need to find a way to detect which web part called the field override.

Paul Hunt posted a solution in his blog post “ListView Web Part issues with JSLink and Display Templates – A solution?“. This solution works great, but what I was looking for is a more generic approach.

One thing that has all list view web parts in common is the view. Every list view web part has its own view id. This characteristic is independent of list template type or any other property and can used in all approach.

You now might wonder if the view id won’t change, when the view of the web part changes. Actually No.

The view id always stays the same as long as the web part is added to the page. If you remove the web part and re-add it you will get a new view ID. All view changes, that will be made on an existing web part will result in the same view id. Even if you changed one of the default list views. What SharePoint actually does is to copy the view configuration to the same view id.

Get View ID from web part

To me the view ID is the only constant in the game of applying JSLink to only some web parts. It’s convenient to have a javascript object that stores all the information. The only downside of using the view id is that is not directly visible in the HTML source code.

This can be solved using a simple trick. To display additional information such as the view id the best option from my point of view is the footer that can be appended to any web part. To display the view ID we only need to add the following code inside the overwrite.

Update April 2015: The code shown below is out dated – Read the whole story on: Footer override might break the pagination if the code is used this way.

... Templates: { Footer: function(ctx){ // Check if display mode have already been requested // Otherwise request display mode if(!displayMode){ // Fetch the display mode displayMode = document.getElementById("MSOSPWebPartManager_DisplayModeName"); // Check if displayMode has been set to Design // If so show debugging information if(displayMode.value == "Design"){ showFooterDebugInfo = true; } else { showFooterDebugInfo = false; } } // If it is not Design aka Web Part Edit view // Don't show View ID if(showFooterDebugInfo === false){ return ""; } // Show View ID in web part edit mode return "<strong>View ID:</strong> "+ctx.view; }, Fields: { ...

The variables “displayMode” and “showFooterDebugInfo” are defined as global variables. This avoids requesting the same value for every web part because of the page only one DisplayModeName can be assigned. You can copy the code right before the field override or download the complete code at the end of this blog post.

The result of this code, the view ID will only be displayed on the web part edit view.

The next thing that is left to do is to check the override against a specific view.

Check field override against the view

Now the last thing left to do is to add a simple “if-Statement”, inside the field override. If the current view requested from the context object matches the id of the configured view return the reformatted strings; otherwise just return the actual value.

The code needs to be extended with the following lines:

... Fields: { Sum:{ View: function(ctx){ // Float value of field var sumValue = ctx.CurrentItem['Sum.']; // Text value displayed var sumText = ctx.CurrentItem.Sum; // Check if current web part matches the defined view if(ctx.view != '{AEC4F0D8-464E-4E40-A9E0-5C898BEA6A02}'){ return ctx.CurrentItem.Sum; } if(sumValue < 0){ return "<span style='color: red'>"+sumText+"</span>"; } else { return "<span style='color: green'>"+sumText+"</span>"; } } } } ...

The result now looks as expected. The first web part shows the highlighted “Sum”-Field according to the values.

Negative values will be rendered in red; positive values will be rendered in green. The web part below shows the values unchanged.

Summary

In this blog post I showed how different field overrides override can be applied to only certain web parts based on the same list template type. The following three things I think are important to remember:

Dealing with Number fields in JS Link

A period behind the field name shows that the field is numeric. This can be accessed using array short notation on the JavaScript Object.

Use static information to bind overrides

The view ID is such a static information that remains on the page however you configure your web part. The only thing that will lead to a new view id is to remove the web part and add a new web part.

So this was the last blog post for this year.

I wish you all a good start into the new year !!!

Further reading

List View Web Parts and JSLink Display Template rendering issues

Share this: Twitter

Facebook

LinkedIn

Email

More

Print

Reddit





Like this: Like Loading...