Second Life of a Hungarian SharePoint Geek

February 15, 2016

Highlighting Closed Risks by Setting Their Color

Filed under: Client-side rendering, JavaScript, SP 2013 — Tags: , , — Peter Holpar @ 23:48

Just after I implemented a solution to display closed risks using strikethrough text, the users suddenly had a new idea. They meant it would be even better, if the whole row, I mean the text of each fields would be displayed grayed out for the closed risks in the list view.

First I thought it should be rather easy, as in the case we should set the background color of the row depending of a field value as described here and here, but I was wrong. So what’s the difference between setting the background color vs. setting the text color, what makes it to be a bit more complicated the latter one?

The problem is, that the cells of the table (the TD HTML elements) that build up the list view already have typically a color defined in the CSS classes they are decorated with (like ms-vb2, ms-vb-title for the Title field, ms-vb-user for the field type Person or Group, etc.). And since the color defined in the style of the elements itself (in this case TD) has a priority, we cannot override it simply by defining a style in the parent (in this case TR) element. In the case of the background color samples referenced above, the background color defined on the row level (TR) was simply inherited to the cell level (TD), as it was not explicitly defined on the TD level.

The following screenshot illustrates the list view before the customizations:

image

How to solve the situation? We could still define the CSS rules necessary to override the default colors for the selected rows. Let’s see how to achieve that!

In this case I utilized jQuery to simplify DOM search and manipulation.

I decorated the rows representing closed risk items with a custom class closedRiskRow:

if (rows[i]["Status"] == "(3) Closed") {
    var rowId = GenerateIIDForListItem(ctx, rows[i]);
    jQuery(jq(rowId)).addClass("closedRiskRow");
}

In the above code I use the jq helper function (see description here), since the Ids of the TR elements contain commas, that is interpreted as CSS notation:

function jq(myid) {
    return "#" + myid.replace(/(:|\.|\[|\]|,)/g, \\$1);
}

I injected the styles dynamically on document load:

jQuery(document).ready(function () {
    jQuery("<style>" + closedRiskRowStyle + "</style>").appendTo("head");

});

The styles are defined using the MultiString helper function, borrowed from Muawiyah Shannak, see this example.

var MultiString = function (f) {
    return f.toString().split(‘\n’).slice(1, -1).join(‘\n’);
}

var closedRiskRowStyle = MultiString(function () {/**
.closedRiskRow > td {
    color: lightgray; 
}

.closedRiskRow > td a.ms-subtleLink {
    color: lightgray; 
}

.closedRiskRow > td a.ms-listlink {
    color: lightgray;
    text-decoration: line-through;  
}
**/
});

The first CSS rule above formats the standard cells, the second one the field type Person or Group, in this case Assigned To field, and the last one is responsible for the Title field, including the strikethrough formatting we already had in the last post.

The full code is included here for your convenience:

  1. var MultiString = function (f) {
  2.     return f.toString().split('\n').slice(1, -1).join('\n');
  3. }
  4.  
  5. var closedRiskRowStyle = MultiString(function () {/**
  6. .closedRiskRow > td {
  7.     color: lightgray;  
  8. }
  9.  
  10. .closedRiskRow > td a.ms-subtleLink {
  11.     color: lightgray;  
  12. }
  13.  
  14. .closedRiskRow > td a.ms-listlink {
  15.     color: lightgray;
  16.     text-decoration: line-through;   
  17. }
  18. **/
  19. });
  20.  
  21. function jq(myid) {
  22.     return "#" + myid.replace(/(:|\.|\[|\]|,)/g, "\\$1");
  23. }
  24.  
  25. (function () {
  26.     if (typeof window.CompletedRiskTemplate == "object") {
  27.         return;
  28.     }
  29.  
  30.     window.CompletedRiskTemplate = {
  31.         HighLightRow: function (inCtx) {
  32.             jQuery(document).ready(function () {
  33.                 jQuery("<style>" + closedRiskRowStyle + "</style>").appendTo("head");
  34.  
  35.                 var rows = inCtx.ListData.Row;
  36.                 if (rows) {
  37.                     for (var i = 0; i < rows.length; i++) {
  38.                         if (rows[i]["Status"] == "(3) Closed") {
  39.                             var rowId = GenerateIIDForListItem(ctx, rows[i]);
  40.                             jQuery(jq(rowId)).addClass("closedRiskRow");
  41.                         }
  42.                     }
  43.                 }
  44.             });
  45.         }
  46.     };
  47.     function _registerCompletedRiskHighLightRowTemplate() {
  48.         var HighLightRowContext = {
  49.             "OnPostRender": window.CompletedRiskTemplate.HighLightRow
  50.         };
  51.  
  52.         SPClientTemplates.TemplateManager.RegisterTemplateOverrides(HighLightRowContext);
  53.     }
  54.     ExecuteOrDelayUntilScriptLoaded(_registerCompletedRiskHighLightRowTemplate, 'clienttemplates.js');
  55. })();

I deployed the .js file to a path under the layout folder as /YourHive/js/highlightClosedRisks.js, and the jquery-1.9.1.min.js to the same folder, then registered the scripts using the following PowerShell code:

$web = Get-SPWeb http://YourProjServer/PWA/Proj1
$list = $web.Lists["Risks"]

$field = $list.Fields.GetFieldByInternalName("LinkTitle")
$field.JSLink = "~sitecollectionlayouts/YourHive/js/jquery-1.9.1.min.js|~sitecollectionlayouts/YourHive/js/highlightClosedRisks.js"
$field.Update()

After the customizations the closed risk is displayed in gray, the title of the risk is with a strikethrough:

image

Leave a Comment »

No comments yet.

RSS feed for comments on this post. TrackBack URI

Leave a comment

Blog at WordPress.com.