2014-12-03

Objective:

  • implement custom sort functionality for list items
  • make order number (rank) visible on the list

First, let’s create custom action for reordering items and make hidden field Order visible and sortable on default view with PowerShell.

[void] [System.reflection.Assembly]::LoadWithPartialName("Microsoft.SharePoint") | out-null
# Add "Change item Order" button at target List
$siteUrl = "yourSiteCollectionUrl";
$listTitle = "yourListTitle";
$site = Get-SPSite -Identity $siteUrl;
$web = $site.OpenWeb();
$list = $web.Lists[$listTitle];
$list.UserCustomActions.Clear();
$action = $list.UserCustomActions.Add();
$action.Location = "CommandUI.Ribbon";
$action.Sequence = 85;
$action.Title = "PS.OrderItems";
$action.CommandUIExtension =
[string]::Format(
"<CommandUIExtension>
<CommandUIDefinitions>
<CommandUIDefinition
  Location=""Ribbon.ListItem.Actions.Controls._children"">
<Button Id=""ReOrderAction.Button"" TemplateAlias=""o1""
  Command=""ReOrderCommand"" CommandType=""General""
  LabelText=""Change Item Order""
Image16by16=""/_layouts/1033/images/formatmap16x16.png""
  Image16by16Top=""-192"" Image16by16Left=""-144""
Image32by32=""/_layouts/1033/images/formatmap32x32.png""
  Image32by32Top=""-192"" Image32by32Left=""-288""/>
</CommandUIDefinition>
</CommandUIDefinitions>
  <CommandUIHandlers>
<CommandUIHandler Command =""ReOrderCommand""
  CommandAction=""{0}/_layouts/15/Reorder.aspx?List={1}"" />
</CommandUIHandlers>
 </CommandUIExtension>",
$web.ServerRelativeUrl.TrimEnd('/'), $list.ID);
$action.Update();
$view = $list.DefaultView;
$view.Query = [string]::Format("<OrderBy><FieldRef Name=""Order""
Ascending=""TRUE""/></OrderBy>");
$view.Update();
Write-Host "-------------------------------------"
Write-Host "Change item order button added successfully for
the list :  " $list.Title -foregroundcolor Green -nonewline
Write-Host " in the site  : " $site.Url -foregroundcolor Green
Write-Host "-------------------------------------"
$web.Dispose();
$site.Dispose();

or use your preferred method. But you can’t change it in SharePoint Manager 2013.

Now we can sort the list based on order, but, we have one issue: how to display order number on the list. This is tricky, because Order field contains double numbers and it has nothing to do with position/rank number. We can use CSR/JSLink to rank Order value within Order value array. Then let’s write a JSLink script for Order field override on view

(function() {
    varmyarray = [];
    varordFieldCtx = {};
    // Define template variable 
    ordFieldCtx.Templates = {};
    ordFieldCtx.Templates.Fields = {
        "Order": {
            "View": OrderFieldViewTemplate
        }
    };
    // Register the template override with SP2013
        SPClientTemplates.TemplateManager.RegisterTemplateOverrides(
    ordFieldCtx
    );
})();
functiongetRank(item, orderval) {
    varranks = $.grep(orderval, function(item, idx) {
        returnitem != orderval[idx - 1];
    });//.reverse(); add this if you want to have reverse ranking
    varrank = $.inArray(item, ranks) + 1;
    returnrank;
}
// Override Order field with rank
functionOrderFieldViewTemplate(ctx) {
    var_orderValue = ctx.CurrentItem.Order;
    varordervalues=[];
    varObjKeys = Object.keys(ctx.ListData.Row);
    ObjKeys.forEach(function(ord){
    ordervalues.push(ctx.ListData.Row[ord].Order);
    });
returngetRank(_orderValue,ordervalues);
}

Save it to the file and place in to master page gallery as JS Display template. (Read this if need info how to). Do not forget to include JQuery link on list webpart JSLink field property in format like:

~site/SiteAssets/jquery-1.8.3.min.js|~site/_catalogs/masterpage/Display Templates/rankNumbers.js

About the author 

PauliusKe