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
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!
Thanks
Helena
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!
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;
}
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...
send me an example.
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.
- 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.
- Set the SortExpression attribute to the UniqueName of the column for GridTemplateColumns.
This allows the code to find the correct column index. - 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"
);
}
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
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?
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
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.