This how-to demonstrates how to enable sorting on a basic JS Grid control. This how-to builds on the How to: Create a Basic JS Grid topic in the SharePoint 2010 SDK, and assumes that you've created a basic JS Grid control as outlined in that topic.

Prerequisites

  • Microsoft SharePoint Foundation 2010
  • Microsoft Visual Studio 2010
  • Completion of How to: Create a Basic JS Grid

Creating a sortable grid

Creating a sortable grid involves the following steps:

  1. Enabling sort behaviour on columns
  2. Using a JS Grid delegate to handle the sort in ECMAScript (JavaScript, Jscript)

  3. Writing a callback to sort the data and rebind the grid

To enable sorting with IsSortable property

  1. Open the JsGrid solution you created in the previous how-to.
  2. Open GridUtilities.cs.
  3. In GetGridColumns method, set the IsSortable property of GridColumn to true. To  make specific columns sortable, use conditional statements on the column name, which is unique.

 The code should appear as follows:

public static IList<GridColumn> GetGridColumns(DataTable table)

{

    List<GridColumn> r = new List<GridColumn>();

    foreach (DataColumn iterator in table.Columns)

    {

        /* Columns are visible in the grid; we don't want these

            as grid columns. */

        // HierarchyParentKey is used in the How to: Create a Hierarchy Grid topic.

 

        if (iterator.ColumnName != "Key"

                && iterator.ColumnName != GridSerializer.DefaultGridRowStyleIdColumnName

            //&& iterator.ColumnName != GridSerializer.DefaultGanttBarStyleIdsColumnName // uncomment for the Create a Gantt Chart Using JS Grid How-To.

                && iterator.ColumnName != "HierarchyParentKey"

                && iterator.ColumnName.Substring(0, 5) != "costq"

                && iterator.ColumnName.Substring(0, 5) != "Quart")

        {

            GridColumn col = new GridColumn();

            // Point the column at a fieldKey name.

            col.FieldKey = iterator.ColumnName;

            // Give the column header a name.

            col.Name = iterator.ColumnName;

            // Define the column width.

            col.Width = 210;

            // Enable sorting for the column

            col.IsSortable = true;

 

            // Define column settings.

            if (iterator.ColumnName == "Department")

            {

                col.IsHidable = false;

            }

            if (iterator.ColumnName == "Yearly Estimate")

            {

                col.IsSortable = true;

            }

 

            // Add the column.

            r.Add(col);

        }

    }

    return r;

}

Note that IsSortable property is used to enable or disable sorting on GridColumn. The IsSortable property is set to false by default. 

Using a JS Grid delegate to handle the sort

The JS Grid control supports a variety of delegates. The Sort delegate is used to handle sort on grid. For the list of delegates supported by JS Grid control refer JS Grid Delegates. 

 

To use the Sort delegate

 

  1. Open the JSGrid solution.
  2. Open JSGridWebPartUserControl.ascx.
  3. Add the following to the ECMAScript code:
  • jsGridControl.SetDelegate(SP.JsGrid.DelegateType.Sort, HandleSort);
  • HandleSort method to handles the sort event and
  • DisplaySortedData method to rebind the sorted data back to grid

Global level variables are added in order to maintain the sort, and store initial data source bound to grid, which can be reused to bind the grid after callback.

The code should appear as follows:

 

<SharePoint:JSGrid ID="_grid" runat="server" JSControllerClassName="GridManager"

    JSControllerInstanceName="GM" ShowLoadingIndicator="true" />

<script type="text/javascript">

    Type.registerNamespace("GridManager");

    GridManager = function () {

 

        // Variables for the JSGrid control instance and the grid properties.

        var _jsGridControl;

        var _props;

 

        // Variables for sorting.

        var _orderByColumnName;

        var _isDescending;

 

        // Variable for the grid data source.

        var _tableCache;

 

        this.Init = function (jsGridControl, initialData, props) {

 

            // Assign it to global variable

            _jsGridControl = jsGridControl;

            _props = props;

 

            // Delegate to handle sort

            jsGridControl.SetDelegate(SP.JsGrid.DelegateType.Sort, HandleSort);

 

            var dataSource = new SP.JsGrid.StaticDataSource(initialData);

 

            // grid data source

            _tableCache = dataSource.tableCache;

            var jsGridParams = dataSource.InitJsGridParams();

            jsGridControl.Init(jsGridParams);

        }

 

        // HandleSort is called when the ascending/descending header dropdown is clicked.

        function HandleSort(newSortedCols) {

            _orderByColumnName = newSortedCols[0].columnName;

            _isDescending = newSortedCols[0].isDescending;

 

            // Disable the grid while it is being sorted.

            _jsGridControl.Disable();

 

            // Send the sorting values to the server by using a callback.

            var args = Sys.Serialization.JavaScriptSerializer.serialize({

                OrderByColumnName: _orderByColumnName,

                IsDescending: _isDescending

            });

 

            eval(_props.callbackScript);

        }

 

        // The DisplaySortedData function is called through the GridManager instance (named "GM").

        // Bind the sorted data to the JSGrid object, and show the grid again.

        this.DisplaySortedData = function (sortedData) {

            // Show the sorted data in the grid.

            if (sortedData && sortedData != '') {

                var deserializedGridData = SP.JsGrid.Deserializer.DeserializeFromJson(sortedData);

                var jsgridDeserializer = new SP.JsGrid.Deserializer(deserializedGridData, SP.JsGrid.DeserializationMode.RowView, _props.keyColumn);

                _tableCache.Clear();

                _tableCache.AddRawDataToCache(ConvertAssocArrayKeysToArray(jsgridDeserializer.data), jsgridDeserializer.data);

                _jsGridControl.SetRowView(jsgridDeserializer.InitJsGridRowViewParams());

                _jsGridControl.Enable();

            }

        }

 

        function ConvertAssocArrayKeysToArray(assocArray) {

            var r = [];

 

            for (var key in assocArray) {

                r.push(key);

            }

 

            return r;

        }

    };

</script>

 

Note that HandleSort method takes an array of objects as input from grid when the grid is sorted. The array contains the column name and the order (ascending or descending) in which it has to be sorted.

 

Optionally, the JS Grid control can be disabled while sorting, and enabled after sorting, to refrain the grid when it is being sorted. The array of objects should be passed to the server using callback. The client argument has two properties: OrderByColumnName and IsDescending which should be passed to server side, so add equivalent type in the server side.

To do this:

  1. In Solution Explorer, right-click the GridUtils folder, point to Add, and then click New Items. Select Visual C#, select Code, and then select Code File. Name the file CallbackArgs.cs.
  2. Copy the following code to the CallbackArgs.cs file:

using System;

public class CallbackArgs

{

    public String OrderByColumnName;

    public bool IsDescending;

}

 

Writing a callback to sort the data and rebind the grid

To enable a callback event on the server, implement the ICallbackEventHandler interface. The following implementation is specific to this topic.

To write a callback

  1. In JSGrid solution, open JSGridWebPartUserControl.ascx.cs.
  2. Implement the ICallbackEventHandler interface for your partial class. Provide an implementation for the RaiseCallbackEvent and GetCallbackResult method. RaiseCallbackEvent will be invoked from the client to perform the callback on the server. GetCallbackResult will return the callback result to the client.
  3. To enable callbacks, JS Grid exposes the JsInitObject property, which can hold callback event reference.

Add the following declarations:

 

using System;

using System.Data;

using System.Web.Script.Serialization;

using System.Web.UI;

using JSGridSample.GridUtilityLib;

using Microsoft.SharePoint.JSGrid;

using Microsoft.SharePoint.JsonUtilities;

 

Replace the contents of the JSGridWebPartUserControl class with the following.

 

public partial class JSGridWebPartUserControl : UserControl, ICallbackEventHandler

{

    private string KeyColumn = "Key";

 

    protected void Page_Load(object sender, EventArgs e)

    {

        // Build some simple data for the grid to display

        DataTable data = new GridData().Data(20);

 

        // Create a grid serializer to connect to data

        GridSerializer gds = new GridSerializer(

            SerializeMode.Full,

            data,

            KeyColumn,

            new FieldOrderCollection(new String[] { "Title" }),

            GridUtilities.GetGridFields(data),

            GridUtilities.GetGridColumns(data));

 

        // Set the grid serializer at the grid serializer data

        _grid.GridDataSerializer = gds;

 

        _grid.JsInitObject = new

        {

            callbackScript = this.Page.ClientScript.GetCallbackEventReference(

                this,

                "args",

                "GM.DisplaySortedData",

                "true",

                true),

            keyColumn = KeyColumn

        };

    }

 

    #region Callback event

 

    private CallbackArgs _callbackArgs;

 

    public string GetCallbackResult()

    {

        // Build some simple data for the grid to display

        DataTable data = new GridData().Data(20);

 

        // Create a grid serializer to connect to data

        GridSerializer gds = new GridSerializer(

            SerializeMode.RowView,

            data,

            KeyColumn,

            new FieldOrderCollection(new[] { _callbackArgs.OrderByColumnName }, new[] { _callbackArgs.IsDescending }),

            GridUtilities.GetGridFields(data),

            GridUtilities.GetGridColumns(data));

 

        var serializer = new Serializer();

        return gds.ToJson(serializer);

    }

 

    // Raise a callback event.

    public void RaiseCallbackEvent(string eventArgument)

    {

        // Deserialize callback arguments from JSON

        _callbackArgs = new JavaScriptSerializer()

            .Deserialize<CallbackArgs>(eventArgument);

    }

 

    #endregion

}

 

Note that, in RaiseCallbackEvent method, the argument from client method HandleSort is type-casted to server side equivalent type CallbackArgs. GetcallbackResult method serializes the sorted data and returns to the client method DisplaySortedData(using callback event reference) in the form of JSON. DisplaySortedData gets the sorted data, deserializes it and rebinds the grid. Do not forget to enable the grid if it is disabled while sorting.

 

To test the Js Grid sorting

  1. Run the project.
  2. Mouse over one of the column headers. On the right side of the column you see a dropdown.
  3. On clicking the dropdown, you can see two buttons generated: Sort Ascending and Sort Descending.
  4. Click either button. The grid will be refreshed with data sorted accordingly.