Wednesday, April 23, 2014

Sorting a view on the Document ID column in SharePoint 2013/Online

I got a request yesterday where a user wanted to be able to sort a list view via the column heading of the Document ID column. Out of the box this is not doable as the column shown is a URL redirect column which is not sortable, and not the Document ID column iteself.

Read more: You can read more about configuring and activating Document IDs at office.microsoft.com

image

I know there are posts out there which shows how to do this in SharePoint 2010 using SPD, but those days are gone. So what’s the approach then? JS Link!
The underlying column used for Document ID in the view is _dlc_DocIdUrl, and the column you want to sort on is _dlc_DocId.

The steps to enable sorting of this column is two fold, one is to enable sorting in the UI on the Document ID column and the other is to make sure it’s sorting on _dlc_DocId when you click it, and not _dlc_DocIdUrl.

Step 1 – Create the JS Link file and hook it up to the XsltListView Web Part

Fist create an empty file named DocIdSort.js. Upload this file to a new folder named JSLink in the Style Library folder of the site (or any other location you deem suitable). I also uploaded a copy of jQuery to this library, which I’ll use when setting the correct sorting column.

image

Next navigate to the list view you want to add the sorting on. Click the cog wheel in the upper right corner and click Edit Page. Next click Edit Web Part for the XsltListView web part. Expand the Miscellaneous settings and paste the following into the JS Link field. Remember to replace the path’s with the location of the library you used for the .js files.

~site/Style Library/JSLink/jquery-1.11.0.min.js|~site/Style Library/JSLink/DocIdSort.js

image

The above line will first load jQuery, then your JS Link code file, guaranteeing jQuery is loaded when the other code runs.

Click OK in the web part and Stop Editing for the page to save your settings.

Step 2 – Fill in the JS Link logic

While browsing your view do a view source of the page in your browser (Chrome will show all content while IE don’t show dynamically rendered content without using Developer Tools – F12 key). In the HTML search for ctx.BaseViewID and ctx.ListTemplateType. The values of these two properties are needed for the JSLink script later.

image

Open up the DocIdSort.js file (for example via Open in Explorer) and add the following snippet where you replace the BaseViewID and ListTemplateType with the numbers you found in the page markup.
function SetDocIdAsSortable(ctx) {
    for(var i=0; i<=ctx.ListSchema.Field.length; i++){
        if(ctx.ListSchema.Field[i].RealFieldName == "_dlc_DocIdUrl" )
        {
            ctx.ListSchema.Field[i].Sortable = "TRUE";
            break;
        }
    }
}

// anonymous self-executing function to hook up JS Link templates for the view
(function () {
    var overrideCtx = {};
    overrideCtx.OnPreRender = SetDocIdAsSortable;
    overrideCtx.BaseViewID = 20;
    overrideCtx.ListTemplateType = 10056;
    SPClientTemplates.TemplateManager.RegisterTemplateOverrides(overrideCtx);
})();


imageWhat this code does is make the Document ID column render as a sortable column. You change the field definition before it’s rendered in the OnPreRender function.  Once you save the DocIdSort.js file the Document ID column should now render in blue and show the sorting menu.


However, if you pick Ascending or Descending the list will try to be sorted on the _dlc_DocIdUrl column, which does not work.


To fix this you need add a post render function as well, and this is where jQuery comes in.

The full contents of DocIdSort.js is below.
function SetDocIdAsSortable(ctx) {
    for(var i=0; i<=ctx.ListSchema.Field.length; i++){
        if(ctx.ListSchema.Field[i].RealFieldName == "_dlc_DocIdUrl" )
        {
            // Render the column as a sortable column
            ctx.ListSchema.Field[i].Sortable = "TRUE";
            break;
        }
    }
}

function SetCorrectSortColumn(ctx) {
    var j = jQuery.noConflict();
    // Locate Document ID column in markup
    var column = j("div[name=_dlc_DocIdUrl]");
    var sortFields = column.attr("sortfields");
    // Replace the field value
    sortFields = sortFields.replace("_dlc_DocIdUrl", "_dlc_DocId");
    column.attr("sortfields", sortFields);
}

// anonymous self-executing function to hook up JS Link templates for the view
(function () {
    var overrideCtx = {};
    overrideCtx.OnPreRender = SetDocIdAsSortable;
    overrideCtx.OnPostRender = SetCorrectSortColumn;
    overrideCtx.BaseViewID = 20;
    overrideCtx.ListTemplateType = 10056;
    SPClientTemplates.TemplateManager.RegisterTemplateOverrides(overrideCtx);
})();

Sorting on Document ID should now work and if you look at the URL it should look something like below where it’s sorted on ID in ascending order.

/Forms/AllDocuments.aspx#InplviewHash93b53a21-81b2-4a81-9bae-e6fa0f074afe=SortField%3D_dlc_DocId-SortDir%3DAsc

PS! Make sure you check in and publish your .js files for them to work for all users once you have the final version.