This is a migrated thread and some comments may be shown as answers.

pure client side Sort for RadGrid

12 Answers 477 Views
Grid
This is a migrated thread and some comments may be shown as answers.
HL
Top achievements
Rank 1
HL asked on 06 Jul 2011, 11:07 PM

Hi all:
  I saw lots of topic regarding RadGrid client sort topic and  I couldn't get the answer after I searched lots.most of them using PageMethods.function -- still call function on server side. Is it any way not to go to server side and sort on clientside only?
 I tried to use the following sample but I can't figure out where I can get data from. I don't use the webservice so can't use PageMethods.functionName(). Also I don't want to go to server at all. Is it possible?

Thanks
Helena

 

 

function RadGridAlertsWidget_SortCommand(sender, args) 
{
      var tableView = sender.get_masterTableView();
    var sortExpressions = tableView.get_sortExpressions();
     var fieldName = sortExpressions.getItem(0).get_fieldName();
     var sortOrder = sortExpressions.getItem(0).get_sortOrder();
     //tableView.set_datasource(???)
    tableView.dataBind();
    // sender.dataBind();
   args.set_cancel(true);
      }

12 Answers, 1 is accepted

Sort by
0
Veli
Telerik team
answered on 12 Jul 2011, 08:05 AM
Hello Hl,

Pure client-side sorting is not supported in RadGrid. You need to call the web service/page method/ URL that provides your data when you need to sort. RadGrid then expects the sorted data to be returned in the response. If you need to simulate this approach entirely on the client-side, you can hook to the client-side OnCommand event, check for the Sort command, cancel the command to prevent default behavior, sort the data programmatically with javascript and pass the sorted result back to the grid using RadGrid.get_masterTableView().set_dataSource().

Greetings,
Veli
the Telerik team

Register for the Q2 2011 What's New Webinar Week. Mark your calendar for the week starting July 18th and book your seat for a walk through of all the exciting stuff we will ship with the new release!

0
HL
Top achievements
Rank 1
answered on 12 Jul 2011, 02:42 PM
Do you have example how to pass the sorted result back to the grid using RadGrid.get_masterTableView().set_dataSource()?

Thanks
Helena


0
Veli
Telerik team
answered on 13 Jul 2011, 11:51 AM
Sure, I have created a test page for you. It demonstrates a client-bound RadGrid where sorting is implemented totally on the client and the result is passed back to the grid. We use a custom sort function to sort the grid data by the sort expressions provided from RadGrid.

Veli
the Telerik team

Register for the Q2 2011 What's New Webinar Week. Mark your calendar for the week starting July 18th and book your seat for a walk through of all the exciting stuff we will ship with the new release!

0
Jack
Top achievements
Rank 1
answered on 21 May 2013, 07:23 AM
your example is working fine but my Case is little different
here is my grid
<telerik:RadGrid ID="RadGrid1" runat="server" AutoGenerateColumns="False" CellSpacing="0"
            GridLines="None" AllowSorting="true" AllowPaging="true" PageSize="2" OnNeedDataSource="RadGrid1_NeedDataSource">
            <MasterTableView>
                <Columns>
                    <telerik:GridBoundColumn DataField="dept" DataType="System.Byte" FilterControlAltText="Filter dept column"
                        HeaderText="dept" ReadOnly="True" SortExpression="dept" UniqueName="dept">
                    </telerik:GridBoundColumn>
                    <telerik:GridBoundColumn DataField="current_year" DataType="System.Decimal" FilterControlAltText="Filter current_year column"
                        HeaderText="current_year" SortExpression="current_year" UniqueName="current_year">
                    </telerik:GridBoundColumn>
                    <telerik:GridBoundColumn DataField="previous_year" DataType="System.Decimal" FilterControlAltText="Filter previous_year column"
                        HeaderText="previous_year" SortExpression="previous_year" UniqueName="previous_year">
                    </telerik:GridBoundColumn>
                </Columns>
            </MasterTableView>
            <ClientSettings>
            </ClientSettings>
            <ClientSettings>
                <ClientEvents OnGridCreated="gridCreated" OnCommand="gridCommand" />
            </ClientSettings>
        </telerik:RadGrid>

SqlConnection conn = new SqlConnection("Data Source=abc\\SQLEXPRESS;Initial Catalog=Sample;Integrated Security=True");
    protected void RadGrid1_NeedDataSource(object sender, Telerik.Web.UI.GridNeedDataSourceEventArgs e)
    {
        SqlCommand cmd = conn.CreateCommand();
        cmd.CommandType = CommandType.Text;
        cmd.CommandText = "SELECT * FROM [budgets]";
        
        SqlDataAdapter adp = new SqlDataAdapter(cmd);
        DataTable dt = new DataTable();
        adp.Fill(dt);
        RadGrid1.DataSource = dt;
    }
you are binding your grid from javascript and i am binding on neededdatasource
so i am facing problem in binding by javascript and don't want to use webservice or wcf to bind radgrid.is there any solution for that .
when i am using your code i am getting error :
data is not define...
0
Shinu
Top achievements
Rank 2
answered on 21 May 2013, 08:57 AM
Hi,

Please check this help documentation.

Thanks,
Shinu.
0
Jack
Top achievements
Rank 1
answered on 21 May 2013, 09:34 AM
thanks for reply but i am binding my grid at neededdatasource so how can i give set_datasource().
send me an example.
0
Shinu
Top achievements
Rank 2
answered on 23 May 2013, 05:36 AM
Hi,

I guess you want to bind RadGrid from serverside and sort from client side.If this is the desired functionality, unfortunately it is not supported. The sorting functionality is performed over the data source to which the RadGrid is bound. If you bound the RadGrid on the server a post back is needed in order to apply sorting expression and return sorted data. If you want to have client side sorting you need to bind the RadGrid on the client.

Thanks,
Shinu.
0
David
Top achievements
Rank 2
answered on 19 Jun 2013, 01:58 PM
We have written a pure JavaScript sort solution for simple non-hierarchical, non-paged grids bound on the server. I have included the code below. Hopefully someone will find this useful. To use this code you will need to do the following;
  1. Hook up radGrid_Command(sender, args) to the client side command event by using the ClientEvents-OnCommand attribute on the ClientSettings element of the grid.
  2. Set the SortExpression attribute to the UniqueName of the column for GridTemplateColumns.
    This allows the code to find the correct column index.
  3. Set AllowNaturalSort attribute on MasterTableView element to false which will stop all postbacks related to sorting.
    If AllowNaturalSort = true, a postback will occur for the natural sort but the client code will be called for asc and desc sorts.

This was written for our specific purpose and environment and may require some changes to work properly in your environment. This should provide a good launching point for a pure client side sort. From what we have seen so far, this has not affected anything on the server side and the grid works as it should after a client side sort.

var _colIdx;
var _sortOrder;
 
//Event Handler for RadGrid Command event.
function radGrid_Command(sender, args) {
    if (args.get_commandName() == "Sort") {
        //The command is the sort command so cancel the postback and call the client sort.
        args.set_cancel(true);
 
        //Call the custom client side custom sort for rad grid.
        sortRadGrid(sender, args.get_commandArgument());
    }
}
 
//Sorts the passed in rad grid. Should be called from the radGrid_Command client side event.
function sortRadGrid(sender, colSortDataField) {
 
    var masterTbl = sender.MasterTableView;
    var tblObj = masterTbl.get_element();
    var sortExpression = masterTbl.get_sortExpressions().getItem(0);
    _sortOrder = sortExpression.get_sortOrder();
 
    //Determine the selected column index.
    var columns = masterTbl.get_columns();
 
    try {
        for (var k = 0; k < columns.length; k++) {
            if (colSortDataField == columns[k].get_dataField() || colSortDataField == columns[k].get_element().UniqueName)
                _colIdx = k;
        }
 
        if (_colIdx == null)
            throw ("Unable to determine the selected sort column");
    }
    catch (ex) {
        alert("An error has occurred!\n" + (ex.message || ex));
    }
 
    //Determine the row container, rows and row count.
    var rowContainer = tblObj.tBodies[0] || tblObj;
    var rows = rowContainer.rows;
    var rowCnt = rows.length;
 
    var sortArray = new Array(rowCnt);
    for (var i = 0; i < rowCnt; i++)
        sortArray[i] = rows[i];
 
    try {
        //Sort the array of row objects. This uses the function called sortFunction to determine their equality.
        sortArray.sort(function (row1, row2) { return sortTableRows(row1, row2); });
    }
    catch (ex) {
        alert("An error has occurred!\n" + (ex.message || ex));
    }
 
    //Display the changes to the table, setting the proper class for the row.
    for (var j = 0; j < rowCnt; j++) {
        if (j % 2 == 1)
            //Row is an alternate row
            sortArray[j].className = sortArray[j].className.replace("rgRow", "rgAltRow");
        else
            sortArray[j].className = sortArray[j].className.replace("rgAltRow", "rgRow");
 
        rowContainer.appendChild(sortArray[j]);
    }
}
 
//Function for determing two rows equality during sort.
function sortTableRows(row1, row2) {
    var retVal;
 
    //Get the correct cell values, if cell value is empty get inner html;
    var cellVal1 = getCellValue(row1.cells[_colIdx]);
    var cellVal2 = getCellValue(row2.cells[_colIdx]);
 
    //Get value as number if number
    cellVal1 = (isNaN(cellVal1) ? cellVal1 : Number(cellVal1));
    cellVal2 = (isNaN(cellVal2) ? cellVal2 : Number(cellVal2));
 
    //Get value as date if date
    cellVal1 = (isDate(cellVal1) ? new Date(cellVal1) : cellVal1);
    cellVal2 = (isDate(cellVal2) ? new Date(cellVal2) : cellVal2);
 
    //Check their equality for sorting.
    switch (_sortOrder) {
        case 1: //Sort order is ascending.
            retVal = (cellVal1 < cellVal2 ? -1 : 1);
            break;
        case 2: //Sort order is descending.
            retVal = (cellVal2 < cellVal1 ? -1 : 1);
            break;
        default:
            retVal = 0;
            break;
    }
 
    return retVal;
}
 
//Gets the value of the passed in cell or of it's child controls.
function getCellValue(cell) {
    var value;
 
    if (cell.children.length >= 1)
        value = getControlValue(cell);
 
    //Get the inner html if the current value is nothing
    value = value || cell.innerHTML;
 
    return value;
}
 
//Recursive call to get the passed in item's values. Returns a pipe delimeted string containing values of all child controls.
function getControlValue(control) {
    //Get current control's value adding a pipe to delimit in case of recursion.
    var value = "";
 
    //Get the child control's value adding a pipe delimter.
    switch (control.nodeName.toLowerCase()) {
        case "input":
        case "textarea":
            value += (control.type && control.type != "checkbox" ? control.value : control.checked) + "|";
            break;
        case "select":
            switch (control.type) {
                case "select-one":
                    value += control[control.selectedIndex].text + "|";
                    break;
                default:
                    throw ("Multi-select dropdowns are not currently supported by sorting function.");
                    break;
            }
            break;
        case "a":
            if (control.children.length == 0)
                value += control.innerHTML
            else
                for (var i = 0; i < control.children.length; i++)
                    value += getControlValue(control.children[i]) + "|";
            break;
        default:
            value += (control.nodeValue || control.value ? control.nodeValue || control.value  + "|" : "");
 
            if (control.children.length > 0)
                for (var i = 0; i < control.children.length; i++)
                    value += getControlValue(control.children[i]) + "|";
            break;
    }
 
    //Replace the last pipe delimeter.
    if (value != null)
        value = value.substr(0, value.lastIndexOf("|"));
 
    return value;
}
 
//checks to see if passed in value is a day
function isDate(value) {
    var tmpDate = new Date(value);
    return !(tmpDate.toString() == "NaN" || tmpDate.toString() == "Invalid Date");
}
0
Maria Ilieva
Telerik team
answered on 24 Jun 2013, 08:56 AM
Hi David,

Thank you for share your example for simple client sorting. I'm sure it will be of a big help to other users that need to implement similar scenarios.

Regards,
Maria Ilieva
Telerik
If you want to get updates on new releases, tips and tricks and sneak peeks at our product labs directly from the developers working on the RadControls for ASP.NET AJAX, subscribe to the blog feed now.
0
Billy
Top achievements
Rank 1
answered on 22 Aug 2013, 08:03 PM
I've tried the above for pure client side sorting. The sorting itself works well.
However, the args.set_cancel(true) does not seem to be canceling the postback. I've also tried aborting the postback through the page request manager to no avail. So, when the postback occurs the columns come back unsorted.
Any thoughts on canceling the postback?
0
Princy
Top achievements
Rank 2
answered on 23 Aug 2013, 03:15 PM
Hi Billy,

I have tried the above code and it works fine.One suggestion to prevent postback on clicking the header is you can use RadAjaxPanel or RadAjaxManager.
Please try and see if it helps.

Thanks,
Princy
0
David
Top achievements
Rank 2
answered on 29 Aug 2013, 08:39 PM
Billy,
I believe that you may have the AllowNaturalSort property set to true (the default value). When this is set to true, it will post back the third time you click a column to rebind the grid in it's natural sort order. This can be set on the MasterTableView element or GridTableView object.

Also, on a side note. This code only sorts the table object and not the underlying DataItems that are part of the grid. After a sort, if you need to run any JavaScript against controls contained in the row, you may have to find the data item that matches the row as it will be in a different position.
Tags
Grid
Asked by
HL
Top achievements
Rank 1
Answers by
Veli
Telerik team
HL
Top achievements
Rank 1
Jack
Top achievements
Rank 1
Shinu
Top achievements
Rank 2
David
Top achievements
Rank 2
Maria Ilieva
Telerik team
Billy
Top achievements
Rank 1
Princy
Top achievements
Rank 2
Share this question
or