Skip to content

Instantly share code, notes, and snippets.

@estruyf
Created December 3, 2014 08:16
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save estruyf/9bd3fad82be77978c99c to your computer and use it in GitHub Desktop.
Save estruyf/9bd3fad82be77978c99c to your computer and use it in GitHub Desktop.
SPSUK Demo Sorting (Control template)
<html xmlns:mso="urn:schemas-microsoft-com:office:office" xmlns:msdt="uuid:C2F41010-65B3-11d1-A29F-00AA00C14882">
<head>
<title>List Table Control</title>
<!--[if gte mso 9]><xml>
<mso:CustomDocumentProperties>
<mso:TemplateHidden msdt:dt="string">0</mso:TemplateHidden>
<mso:MasterPageDescription msdt:dt="string">This is the table layout control template.</mso:MasterPageDescription>
<mso:ContentTypeId msdt:dt="string">0x0101002039C03B61C64EC4A04F5361F385106601</mso:ContentTypeId>
<mso:TargetControlType msdt:dt="string">;#Content Web Parts;#</mso:TargetControlType>
<mso:HtmlDesignAssociated msdt:dt="string">1</mso:HtmlDesignAssociated>
<mso:HtmlDesignConversionSucceeded msdt:dt="string">True</mso:HtmlDesignConversionSucceeded>
<mso:HtmlDesignStatusAndPreview msdt:dt="string">http://intranet/sites/SPSUK/_catalogs/masterpage/SPSUK/TableLayout/Control_List_Table.html, Conversion successful.</mso:HtmlDesignStatusAndPreview>
</mso:CustomDocumentProperties>
</xml><![endif]-->
</head>
<body>
<script>
Type.registerNamespace('search.TableLayout');
search.TableLayout = function() {
var currentCtx, clientControl, properties;
return {
setContext: function (ctx, cc, props) {
search.TableLayout.setCurrentCtx(ctx);
search.TableLayout.setClientControl(cc);
search.TableLayout.setProperties(props);
},
setCurrentCtx: function (ctx) {
currentCtx = ctx;
},
setClientControl: function (cc) {
clientControl = cc;
},
setProperties: function (props) {
properties = props;
},
// Add the sortable properties to your search context
AddSortableProperty: function (property) {
var availableSorts = currentCtx.DataProvider.get_availableSorts();
availableSorts.push({ "name": property + "ASC", "sorts": [{ "p": property, "d": 0 }] });
availableSorts.push({ "name": property + "DES", "sorts": [{ "p": property, "d": 1 }] });
currentCtx.DataProvider.set_availableSorts(availableSorts);
},
AddUnsortableProperty: function (property) {
if (typeof currentCtx.DataProvider.Unsortable === "undefined") {
// Create an empty unsortable array
currentCtx.DataProvider.Unsortable = [];
}
currentCtx.DataProvider.Unsortable.push(property);
},
CheckSortableProperty: function (property) {
var availableSorts = currentCtx.DataProvider.get_availableSorts();
var indexArray = availableSorts.map(function(o){return o.name;});
var currentPropIdx = indexArray.indexOf(property+"ASC");
return currentPropIdx === -1 ? true : false;
},
CheckUnsortableProperty: function (property) {
if (typeof currentCtx.DataProvider.Unsortable !== "undefined") {
var unsortableProps = currentCtx.DataProvider.Unsortable;
return unsortableProps.indexOf(property) === -1 ? true : false;
} else {
return true;
}
},
HideSortableOptions: function (property) {
var elm = document.getElementById(property.replace(/ /g, '-'));
if (elm !== null) {
elm.style.display = 'none';
}
},
SetCurrentSorting: function () {
var queryState = currentCtx.DataProvider.get_currentQueryState().o;
if (queryState !== null && queryState.length > 0) {
var sortName = queryState[0].p;
var sortDir = queryState[0].d;
if (!Srch.U.e(sortName)) {
var elm = document.getElementById(sortName.replace(/ /g, '-'));
if (elm !== null) {
elm.parentNode.style.fontWeight = "bold";
var sortElm = elm.getElementsByClassName('sortarrow')[0];
if (sortElm !== null) {
if (sortDir === 0){
sortElm.innerHTML = "<img src='/_layouts/15/images/spcommon.png' class='ms-sortarrowdown-icon'>";
} else {
sortElm.innerHTML = "<img src='/_layouts/15/images/spcommon.png' class='ms-sortarrowup-icon'>";
}
}
}
}
}
},
ShowPropertySorting: function () {
// Check if the properties array is empty.
// This can happen if you do not override the managed properties in the web part.
if ($isEmptyArray(properties)) {
if (!Srch.U.n(DisplayTemplateData)) {
if (!Srch.U.n(DisplayTemplateData.ManagedPropertyMapping)) {
properties = DisplayTemplateData.ManagedPropertyMapping;
}
}
}
if (!$isEmptyArray(properties)) {
for (var key in properties) {
if (!Srch.U.e(properties[key])) {
var prop = properties[key].toString();
if (search.TableLayout.CheckSortableProperty(prop)) {
if (search.TableLayout.CheckUnsortableProperty(prop)) {
(function (prop) {
// Do a Ajax call for each property to check if it is sortable
var request = new XMLHttpRequest();
var restUrl = _spPageContextInfo.webAbsoluteUrl + "/_api/search/query?querytext='" + clientControl.get_dataProvider().get_queryTemplate() + "'&sortlist='" + properties[key] +":ascending'&RowLimit=1&selectproperties='Path'";
request.open('GET', restUrl, true);
request.onload = function (e) {
if (request.readyState === 4) {
// Check if the get was successful
if (request.status === 200) {
search.TableLayout.AddSortableProperty(prop);
} else {
search.TableLayout.AddUnsortableProperty(prop);
// Hide the sorting options
search.TableLayout.HideSortableOptions(prop);
}
}
};
request.onerror = function (e) {
// Catching errors
};
request.send(null);
})(prop);
} else {
// Hide the sorting options
search.TableLayout.HideSortableOptions(prop);
}
}
}
}
}
}
}
}();
Srch.U.registerRenderTemplateByName("setcontext", search.TableLayout.setContext);
Srch.U.registerRenderTemplateByName("setcurrentsorting", search.TableLayout.SetCurrentSorting);
Srch.U.registerRenderTemplateByName("showpropertysorting", search.TableLayout.ShowPropertySorting);
</script>
<div id="Control_List">
<!--#_
var tableId = ctx.ClientControl.get_nextUniqueId() + "_table";
if (!$isNull(ctx.ClientControl) &&
!$isNull(ctx.ClientControl.shouldRenderControl) &&
!ctx.ClientControl.shouldRenderControl())
{
return "";
}
// Retrieve the property mappings
var clientControl = ctx.ClientControl;
var properties;
if (!Srch.U.n(clientControl)) {
var propertyMappings = clientControl.get_propertyMappings();
if (!Srch.U.n(propertyMappings) && !Srch.U.w(propertyMappings)) {
properties = Srch.Result.parsePropertyMappingsString(propertyMappings);
}
}
// Set the current context, client control, properties
Srch.U.getRenderTemplateCollection().setcontext(ctx, clientControl, properties);
AddPostRenderCallback(ctx, function() {
// Show or hide the sort options
Srch.U.getRenderTemplateCollection().showpropertysorting();
// Show the current sort option
Srch.U.getRenderTemplateCollection().setcurrentsorting();
});
ctx.ClientControl.set_showSortOptions(true);
ctx.ListDataJSONGroupsKey = "ResultTables";
var ListRenderRenderWrapper = function(itemRenderResult, inCtx, tpl)
{
var iStr = [];
iStr.push(itemRenderResult);
return iStr.join('');
}
ctx['ItemRenderWrapper'] = ListRenderRenderWrapper;
_#-->
<table id="_#= tableId =#_" class="cbs-List">
_#= ctx.RenderGroups(ctx) =#_
</table>
<!--#_
var showPaging = ctx.ClientControl.get_showPaging();
if(showPaging)
{
var pagingInfo = ctx.ClientControl.get_pagingInfo();
showPaging = !$isEmptyArray(pagingInfo);
if(showPaging)
{
var currentPage = null;
var firstPage = pagingInfo[0];
var lastPage = pagingInfo[pagingInfo.length - 1];
for (var i = 0; i< pagingInfo.length; i++)
{
var pl = pagingInfo[i];
if (!$isNull(pl))
{
if (pl.startItem == -1)
{
currentPage = pl;
}
}
}
var getPagingImageClassName = function(buttonClassNamePrefix, isNext, isEnabled)
{
var className = buttonClassNamePrefix;
className += (isNext && !Srch.U.isRTL()) || (!isNext && Srch.U.isRTL()) ? "right" : "left";
if(!$isNull(isEnabled) && isEnabled == false)
{
className += "-disabled";
}
return className;
}
var getPagingContainerClassName = function(buttonClassNamePrefix, isEnabled)
{
var className = buttonClassNamePrefix;
className += isEnabled ? "enabled" : "disabled";
return className;
}
var hasNextPage = lastPage.pageNumber == -2;
var hasPreviousPage = firstPage.pageNumber == -1;
var buttonClassNamePrefix = "ms-promlink-button-";
var nextPageContainerClassName = getPagingContainerClassName(buttonClassNamePrefix, hasNextPage);
var previousPageContainerClassName = getPagingContainerClassName(buttonClassNamePrefix, hasPreviousPage);
var nextPageImageClassName = getPagingImageClassName(buttonClassNamePrefix, true, hasNextPage);
var previousPageImageClassName = getPagingImageClassName(buttonClassNamePrefix, false, hasPreviousPage);
_#-->
<div class="ms-promlink-header">
<span class="ms-promlink-headerNav">
<a class="ms-commandLink ms-promlink-button _#= $htmlEncode(previousPageContainerClassName) =#_" title="_#= $htmlEncode(firstPage.title) =#_" href="#" onclick='$getClientControl(this).page(_#= $htmlEncode(firstPage.startItem) =#_);return Srch.U.cancelEvent(event);'>
<span class="ms-promlink-button-image">
<img class="_#= $htmlEncode(previousPageImageClassName) =#_" alt="_#= $htmlEncode(firstPage.title) =#_" src="_#= $urlHtmlEncode(GetThemedImageUrl('spcommon.png')) =#_">
</span>
</a>
<span class="ms-promlink-button-inner"></span>
<a class="ms-commandLink ms-promlink-button _#= $htmlEncode(nextPageContainerClassName) =#_" title="_#= $htmlEncode(lastPage.title) =#_" href="#" onclick='$getClientControl(this).page(_#= $htmlEncode(lastPage.startItem) =#_);return Srch.U.cancelEvent(event);'>
<span class="ms-promlink-button-image">
<img class="_#= $htmlEncode(nextPageImageClassName) =#_" alt="_#= $htmlEncode(lastPage.title) =#_" src="_#= $urlHtmlEncode(GetThemedImageUrl('spcommon.png')) =#_">
</span>
</a>
</span>
</div>
<!--#_
}
}
_#-->
</div>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment