Tuesday, November 10, 2015

Strike through SharePoint 2013 document item based on its status using JS Link

We have a requirement to strike through SharePoint 2013 document item based on its status "Obsolete". If the obsolete is "yes", the column named "Part Number" should be strike through and highlighted as red as in the below screenshot.


The easiest way to implement this is to use SharePoint 2013 new feature JS Link. There are several good JS Link references to highlight a SharePoint list row and color list item with different color. You could refer my previous blog to configure the JS Link. If you add the following javascript as JS Link named Obsolete.js to the display web part, you will get the desired result.

(function () { 

    // Create object that have the context information about the field that we want to change it's output render  
    var priorityFiledContext = {}; 
    priorityFiledContext.Templates = {}; 
    priorityFiledContext.Templates.Fields = { 
        // Apply the new rendering for Obsolate field on List View 
        "Part_x0020_Number": { "View": obsolateFiledTemplate } 
    }; 

    SPClientTemplates.TemplateManager.RegisterTemplateOverrides(priorityFiledContext); 

})(); 

// This function provides the rendering logic for list view 
function obsolateFiledTemplate(ctx) { 

    var title = ctx.CurrentItem[ctx.CurrentFieldSchema.Name]; 

var obsolate = ctx.CurrentItem.Obsolate;
console.log(obsolate);

      // Return html element with appropriate color based on priority value 
if (obsolate == "Yes")
{
return "<span style='color :#f00'>" + "<del>" + title + "</del>" + "</span>"; 
}
else{
return "<span style='color :#000000'>" + title + "</span>"; 
}


The following script will highlight the item to red when obsolete value is "Yes".


(function () {
    var overrideCtx = {};
    overrideCtx.Templates = {};
    overrideCtx.OnPostRender = {
        HighlightRowOverride
    };
    SPClientTemplates.TemplateManager.RegisterTemplateOverrides(overrideCtx);
})();

function HighlightRowOverride(ctx) {

for (var i=0; i< ctx.ListData.Row.length; ++i){

var lid = GenerateIIDFromListItem(ctx, listItem);
var row = document.getElementById(iid);

if (listItem.Obsolate == "Yes") {
row.style.backgroundColor = "rgba(255, 0, 0, 0.5)";
}
}

ctx.skipNextAnimation = true;

}

You will see this implementation is very flexible and we could use this for many other different implementations.

If you need to strike through the Document Name field, you would look at the field using view source. Here is the field definition.

{"Name": LinkFilename",
"FieldType": "Computed",
"RealFieldName": "FileLeafRef",
"DisplayName": "Name",
"ID": "5cc6dc79-3710-4374-b433-61cb4a686c12",
"ClassInfo": "Menu",
"Type": "Computed",
"Filterable": "FALSE",
"listItemMenu": "TRUE",
"CalloutMenu": "TRUE",
"AllowGridEditing": "TRUE"}


You can change the two line of the javascript.

    priorityFiledContext.Templates.Fields = {
        "LinkFilename": { "View": obsolateFiledTemplate }
    };

 var title = ctx.CurrentItem.FileLeafRef;

Please note that you could use powershell or server side API to automatically set the JSLink to the webpart if there are many lists or libraries you need to configure.

Friday, November 6, 2015

Use JSLink to auto populate the SharePoint item field without server side code like custom field

Recently we have a requirement to automatically generate a unique number string for one field called “Part Number” for many SharePoint Document libraries. This unique number string would need to follow some business logic like below.



There are several ways we could implement this. One of the old school method is to implement the field as custom field with business logic to generate unique number string. However, we had several custom fields on SharePoint that caused SharePoint upgrade complexity. In this blog, we will use a new client side implementation JSLink that will not have any server side component. In this way, the solution will be potable and the upgrade will be extremely simple.

The first step is to write a JSLink script named PartNum.js to replace the out of box “Part Number” text field behavior. You would need to find out the field internal name using the way published here. The internal field name for “Part Number” is “Part_x0020_Number“ in our case.  The script will look like below. You would need to update the guid() function with real business logic.

(function () {
    var overrideCtx = {};
    overrideCtx.Templates = {};
    overrideCtx.Templates.Fields = {
        'Part_x0020_Number': { 'NewForm': renderTitle, 'EditForm': renderTitle }
    };
    SPClientTemplates.TemplateManager.RegisterTemplateOverrides(overrideCtx);
})();

function renderTitle(ctx) {

var formCtx = SPClientTemplates.Utility.GetFormContextForCurrentField(ctx);

RegisterCallBacks(formCtx);

        var fieldVal = ctx.CurrentFieldValue ? ctx.CurrentFieldValue.toString() : null;
       
        if(fieldVal) { 
var html = '<div>';
html += '<input id="uniquePartNum" type="text" value=' + fieldVal + '>';
html += '</input>';
html += '</div>';
return html;
}
else{
var newGUID = guid();
var html = '<div>';
html += '<input id="uniquePartNum" type="text" value=' + newGUID + '>';
html += '</input>';
html += '</div>';
return html;  
}
}

//registers call back functions from SharePoint
function RegisterCallBacks(formCtx) {
                //This is what happens when the user clicks save\submit
                formCtx.registerGetValueCallback(formCtx.fieldName, function () {
                                //get the choosen value from the select element
                                var e = document.getElementById("uniquePartNum");
                                return  e.value;
                });
}

// Generate GUID
function guid() {
  function s4() {
    return Math.floor((1 + Math.random()) * 0x10000)
      .toString(16)
      .substring(1);
  }
  return s4() + s4() + '-' + s4() + '-' + s4() + '-' +
    s4() + '-' + s4() + s4() + s4();
}

The second step is to open SharePoint Designer and go to your SiteAssets library, drop PartNum.js there.

The third step is to configure the document item edit form to use this script. Go to your document library and from your library settings ribbon choose ‘Form Web Parts > Default Edit Form’. Edit the webpart. Then add the script to the JS Link field.






Now if you save the changes, you will see the “Part Number” field will be automatically populated with GUID. You could modify the script to generate the string based on your business requirement.

Since Microsoft have changed the development direction for SharePoint 2013 and 2016, you should always think about SharePoint add-in approach instead of server side solution. There are more samples from Microsoft you could refer here.