
If I click a client row, I would like it to simply add that row to the list of selected rows. Right now, the only way to do this is to use the checkbox in the ClientSelectColumn. The problem with this is that a checkbox is a small control, and if you miss your click and end up clicking outside of the checkbox, it clears all previously selected rows and only selects that one row.
I would also like the row click to toggle selection -- click once, it selects. Click again, it deselects. Right now, clicking a row will only select, and to deselect you have to use the checkbox, which can introduce the problem above.
I know it's possible to Ctrl-click to select and deselect, but this has a variety of unwanted effects in the browsers. Firefox adds a border to the table cell that was Ctrl-clicked, and IE selects all the text in that row.
Has anyone figured out a way to have a row select process that's like what I'm seeking?
Josh
38 Answers, 1 is accepted
RadGrid does not provide this functionality out-of-the-box, but it can easily be achieved using client-side events. Here is some sample code:
var clickedItemIndex; |
var deselected; |
var selected; |
function RowClick(sender, args) //Attach to the OnRowClick client event |
{ |
var master = $find('<%= RadGrid1.ClientID %>').get_masterTableView(); |
var index = args.get_itemIndexHierarchical(); |
master.get_dataItems()[index].set_selected(!master.get_dataItems()[index].get_selected()); |
clickedItemIndex = index; |
if(master.get_dataItems()[index].get_selected()) |
selected = true; |
else |
selected = false; |
} |
function RowDeselecting(sender, args) //Attach to the OnRowDeselecting client event |
{ |
if(clickedItemIndex != args.get_itemIndexHierarchical()) |
args.set_cancel(true); |
else if(selected) |
deselected = false; |
else |
deselected = true; |
} |
function RowSelecting(sender, args) //Attach to the OnRowSelecting client event |
{ |
if(clickedItemIndex == args.get_itemIndexHierarchical() && deselected) |
args.set_cancel(true); |
else |
deselected = false; |
} |
The above code implements toggling selected state on row click for RadGrid. The actual selection/deselection is done in the RowClick event handler. Nevertheless, we need some not so straightforward workaround in the RowSelecting and RowDeselecting events, due to the specifics of RadGrid's client-side event cycle. Therefore we conditionally enable and disable the two events based on boolean flags.
Greetings,
Veli
the Telerik team
Instantly find answers to your questions at the new Telerik Support Center

Josh
OK, I will try to be as clear as possible. Please feel free to ask about anything unclear.
The "selected" flag is set to the value of the item.get_selected() property, it directly indicates if an item is selected or not.
As by default, RadGrid clears all selections when a single row is clicked. For example, if you have items 1,3 and 5 selected, clicking on item 2 would select it, but deselect items 1,3 and 5, as of standard implementation. This is fixed in the RowDeselecting event, where we check if the item index for which the RowDeselecting event is fired is the item that is last clicked. If true, this means that the RowDeselecting event is firing for the item we have just clicked, and this event needs to finish, so that we can actually deselect the item. If, however, those two ids do not match, it means that the RowDeselecting event is firing for items that are already selected, but are not clicked. Those are all the items we have previously selected (items 1,3 and 5) and those we need to keep selected. Therefore we check if the currently clicked item is the same item for which the RowDeselecting event is firing. If not, which is the first "if" clause, we cancel the event and keep the items selected.
The "selected" and "deselected" flags are reciprocal in value, if one is true, the other needs to be false. This logic is controlled both in RowDeselecting and RowSelecting events as you can see. The flags are needed, so that if the Select event fires successfully, the Deselect event should be suppresed. And reciprocally, if the Deselect event is fired successfully (a click over a selected item), the Select event should be canceled so that no selection could be made as a result of a row click intended for a deselection.
The "if" clause in the RowSelecting event checks if the Select event has fired for the item that has been clicked, and if the click event cause a row deselection (deselected flag equals true). If both true, this means that the event needs to be canceled, because we should not have a Select event fired for an item that has just been deselected, as this would cause it to be selected again. If the condition is false, the event fires successfully and the "deselected" flag is cleared so that a new cycle can begin.
I hope this is clearer.
All the best,
Veli
the Telerik team
Instantly find answers to your questions at the new Telerik Support Center

- Click on a single row to select that row.
- Click that same row again to deselect it. The row will not deselect.
- Click on one row to select it.
- Click on another row to select it.
- Click the first row to deselect it.
- Click the second row to deselect it. You cannot re-select the second row without first selecting another row.
Josh
You were correct in your observations, some glitches could be recognized in the functioning of the row select. I have since implemented a newer version of the .js file, using a boolean array to store selected information for every grid row. Please find it attached.
Best wishes,
Veli
the Telerik team
Instantly find answers to your questions at the new Telerik Support Center

Thanks so much for your work on this. I implemented the updated javascript and it works perfectly...except in IE. I did all my original testing on Firefox, but when I did a quick compatibility check in IE I discovered that it doesn't work the same way.
I did some rudimentary debugging and it looks like it has to do with the order in which IE fires events versus Firefox. In Firefox, any time I click a row that is not already selected, events fire in this way:
1. RowSelecting
2. RowClick
3. RowDeselecting
4. RowSelecting
After which point the row is properly selected. When I click that same row again to deselect it, the events fire in this way:
1. RowDeselecting
2. RowClick
3. RowSelecting
In IE, when I click a row that isn't selected the events fire in this way:
1. RowSelecting
2. RowDeselecting
3. RowClick
After which point the row is not selected. If I click that same row again, I get events like this:
1. RowSelecting
2. RowSelecting
3. RowClick
It appears that for some reason IE does not fire the RowClick event early enough, resulting in the boolean array not having the proper information about the selection state of the row when the RowSelecting and RowDeselecting events occur. Do you know of any way I can get IE to fire the events in a manageable order?
Thanks,
Josh
PS - I have grown to really hate IE!
Really, it seems the javascript events fire in a different sequence under IE and this is an unexplicable behavior. It seems the javascript engines of the two browsers vary greatly in functioning. I am currently debugging the javascript towards IE, but it seems the closer I get to the desired functionality in IE, the worse it spoils under Firefox. Anyway, I will write back as soon as I find a solution to this issue. Please stay tuned.
Kind regards,
Veli
the Telerik team
Check out Telerik Trainer, the state of the art learning tool for Telerik products.
I was able to get it running on both browsers, using conditional execution of code snippets depending on the browser. I successfully tested it under Firefox 2.0.0.14, IE 7 and Safari. Please find attached the .js file. You need to attach a javascript function to yet another client event - OnRowMouseOver
Kind regards,
Veli
the Telerik team
Check out Telerik Trainer, the state of the art learning tool for Telerik products.

It works fine for selecting and deselecting.The only issue is I have a allowmultirowselect ="false". After I added the js it lets me select multiple rows even though I don't have it set as true.
Can you give me an example where it just lets me select and deselect a single row.
If you would like only one row to be selected at a time, I suggest that you deselect the previously selected row when selecting new one.
Find attached the modified script file.
Best wishes,
Iana
the Telerik team
Check out Telerik Trainer, the state of the art learning tool for Telerik products.

It works perfectly now.

I have a master detail table. Any time the user clicks on a row in the detail table it throws an exception:
"Microsoft JScript runtime error: 'get_dataItems()[...]' is null or not an object"
Can you give a workaround for that.

function
RowSelecting(sender, args)
{
var master = sender.get_masterTableView();
var index = args.get_itemIndexHierarchical();
if(isIE)
{
if(selected[index])
{
args.set_cancel(true);
selected[index] = false;
}
else
{
var index = args.get_itemIndexHierarchical();
if(args.get_tableView().get_name() == "Timesheets")
{
selected[index] = !master.get_dataItems()[index].get_selected();
}
else if(args.get_tableView().get_name() == "TimesheetTracking")
{
var childIndex = index.substring(index.lastIndexOf("_") + 1);
selected[index] = !sender.get_detailTables()[0].get_dataItems()[parseInt(childIndex)].get_selected();
}
}
clickedItemIndex = index;
}
}

I have a similar problem as you have been solving in this thread.
My situation is slightly different. Most importantly, I have a number of RadGrids on the same page.
I am building SharePoint webparts, using RadGrid. The user/developer can place any number of such webparts on the page, i.e. I don't know the number of RadGrid instances on the page.
Since the variables clickedItemIndex, selected, and isIE are global on the page, this won't work.
Can anyone suggest how I can make this work?
Thanks!
/Fredrik
In this case you can try creating the javascript code dynamically and assign different names foe the global variables and functions.
I hope this helps.
Regards,
Iana
the Telerik team
Check out Telerik Trainer, the state of the art learning tool for Telerik products.

Thanks,
Russell.

Multiple selection/deselection on row clicking works like magic with the custom javascript functions you wrote, thanks for your good work, however, one issue is still present: when de-selecting all rows by clicking the checkbox in the grid header, it would only de-select the last selected row.
select all works fine, de-select all doesn't.
can you please take a look in this issue??
Could you please try adding the below javascript method to the ToogleSelection js file:
function CheckedAllClick(sender) |
{ |
if(isIE) |
{ |
var i = 0; |
for(i = 0; i < selected.length; i++) |
{ |
selected[i] = !sender.checked; |
} |
} |
} |
Then handle the ItemCreated event of your RadGrid and add the following code:
protected void RadGrid1_ItemCreated(object sender, GridItemEventArgs e) |
{ |
if (e.Item is GridHeaderItem) |
{ |
GridHeaderItem item = e.Item as GridHeaderItem; |
CheckBox cbAll = item["ClientSelectColumn"].Controls[0] as CheckBox; |
cbAll.Attributes["onclick"] = "CheckedAllClick(this); " |
+ "$find(\"" + RadGrid1.ClientID + "\")._selectAllRows(\"" + RadGrid1.MasterTableView.ClientID + "\", \"\", event);"; |
} |
} |
Let me know if this solves the issue you are facing.
Best wishes,
Iana
the Telerik team
Instantly find answers to your questions on the new Telerik Support Portal.
Check out the tips for optimizing your support resource searches.

Sorry to say this has not fixed anything. It behaves the same - selects all but deselects only one.
Using alerts i've checked all vars in function CheckedAllClick and they seem ok: selected.length is correct no of rows, selected[i] are 'undefined' when selecting and 'true' when deselecting.
My RowDeselecting looks like this (as per ToggleSelection.js):
function RowDeselecting(sender, args) { |
var master = sender.get_masterTableView(); |
var index = args.get_itemIndexHierarchical(); |
var dataItem = master.get_dataItems()[index]; |
var checkbox = dataItem.get_element().getElementsByTagName("INPUT")[0]; |
if (checkbox.disabled) { |
args.set_cancel(true); |
} |
else { |
if (clickedItemIndex != index && selected[index]) { |
//selected[index] = false; // for single row selection |
args.set_cancel(true); //for multi row selection |
} |
} |
} |
Can you try the attached sample and let me know how it works on your end and if I missed something from your logic?
Greetings,
Iana
the Telerik team
Instantly find answers to your questions on the new Telerik Support Portal.
Check out the tips for optimizing your support resource searches.

Have you got a working sample with multiple select enabled without using Ctrl key and de-/select all checkbox working please?
It seems we have some misunderstanding here. I have tried the sample before I sent you and it works fine on my side. I am able to select/deselect rows by clicking on a row or in the ClientSelectColumn checkboxes. However, it seems you are doing something else.
Can you try providing detailed steps on how could I replicate the behavior you experienced?
Sincerely yours,
Iana
the Telerik team
Instantly find answers to your questions on the new Telerik Support Portal.
Check out the tips for optimizing your support resource searches.

the radgridselecting.zip file contains the following files:
App_Data containing Nwind.mdb
Bin containing Telerik dlls
Default.aspx
Default.aspx.cs
Web.config
when I run it, all I see is the sample Grid with no ability to select columns: screenshot
<img src="http://clip2net.com/clip/m7030/1244627253-clip-21kb.png">
are you sure this is what you wanted to show because what you're saying is:
"I have tried the sample before I sent you and it works fine on my side. I am able to select/deselect rows by clicking on a row or in the ClientSelectColumn checkboxes"
?????????????????????
Hello,
Please excuse me for missleading you. It seems I tested another sample, not the sent one. Here should be the right one.
Best wishes,
Ianathe Telerik team
Instantly find answers to your questions on the new Telerik Support Portal.
Check out the tips for optimizing your support resource searches.

Now about your sample. The topic of this conversation is how to enable multiple row selection without holding Ctrl key. Your example does not allow that until you change RowDeselecting(sender, args) method in ToggleSelection.js file as follows:
function RowDeselecting(sender, args) |
{ |
var index = args.get_itemIndexHierarchical(); |
if(isIE) |
{ |
if(clickedItemIndex != index && selected[index]) |
{ |
//selected[index] = false; // for single row selection |
args.set_cancel(true); //for multi row selection |
} |
} |
else |
{ |
if(clickedItemIndex != index && selected[index]) |
{ |
//selected[index] = false; // for single row selection |
args.set_cancel(true); //for multi row selection |
} |
} |
} |
After you do this, you will find that de-selecting all rows checkbox will stop working!
Please look into this as I need to do a release soon.
I see what you mean now. I modified the code a bit and the deselectAll should work properly this time.
Sincerely yours,
Iana
the Telerik team
Instantly find answers to your questions on the new Telerik Support Portal.
Check out the tips for optimizing your support resource searches.

you have fixed the de-/select all functionality, however, there is a new bug: after you select and deselct all rows, you won't be able to select multiple rows without Ctrl key. Please check this is a bug.
I preformed further investigation on this case. And it seems that the current implementation of the GridClientSideColumn and the desired functionality of grid multi row selection/deselection on mouse click are not compatible.
Therefore I suggest that you either use row selection/desection functionality on row click or the GridClientColumn and the default grid functionality for selecting rows.
Please excuse us for the inconvenience.
Best wishes,
Iana
the Telerik team
Instantly find answers to your questions on the new Telerik Support Portal.
Check out the tips for optimizing your support resource searches.

I appreciate that you have tried to replicate the functionality of Windows Explorer where you have to hold Ctrl key in ordered to select multiple rows by clicking on them. However, the grid in web world is totally different control, hence it is expected to behave differently.
As you have possibly noticed a high demand for the functionality requested in the post 1 of this topic, could you please answer a simple question - whether multiple row selection without holding Ctrl key with no bugs of all row select/deselect would ever be implemented?
IMHO this should be an option (property) of Telerik Grid as to whether you need to use Ctrl key to select multiple rows or not.
Indeed, the desired functionality is already implemented in RadGrid. Using GridClientSelectColumn gives you the ability to select/deselect all rows by checking/unchecking single checkbox. Additionally, you can select/deselect separate rows by checking/unchecking the checkbox of the GridClientSelectColumn for the particular row.
Kind regards,
Iana
the Telerik team
Instantly find answers to your questions on the new Telerik Support Portal.
Check out the tips for optimizing your support resource searches.

You can try out the sample in this code library and see if it fulfills your requirements.
Check it out and let me know how it goes.
Regards,
Iana
the Telerik team
Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items.

<telerik:RadGrid ID="radGrid" AllowMultiRowSelection="true" runat="server"> |
<ClientSettings Selecting-AllowRowSelect="true" Selecting-EnableDragToSelectRows="false"> |
<ClientEvents OnGridCreated="GridCreated" OnRowClick="RowClick" OnRowSelecting="RowSelecting" |
OnRowDeselecting="RowDeselecting" OnRowMouseOver="RowMouseOver" /> |
</ClientSettings> |
</telerik:RadGrid> |
var clickedItemIndex; |
var selected; |
var isIE; |
function GridCreated(sender, args) { |
selected = new Array(sender.get_masterTableView().get_dataItems().length); |
isIE = navigator.appVersion.indexOf("MSIE") > 0; |
} |
function RowClick(sender, args) { |
if (!isIE) { |
var master = sender.get_masterTableView(); |
var index = args.get_itemIndexHierarchical(); |
selected[index] = !master.get_dataItems()[index].get_selected() |
clickedItemIndex = index; |
master.get_dataItems()[index].set_selected(!master.get_dataItems()[index].get_selected()); |
} |
} |
function RowDeselecting(sender, args) { |
var index = args.get_itemIndexHierarchical(); |
if (((args.get_domEvent().target) && (args.get_domEvent().target.type == "checkbox")) |
|| ((args.get_domEvent().srcElement) && (args.get_domEvent().srcElement.type == "checkbox"))) { |
selected[index] = false; |
return; |
} |
if (clickedItemIndex != index && selected[index]) { |
args.set_cancel(true); |
} |
} |
function RowSelecting(sender, args) { |
var index = args.get_itemIndexHierarchical(); |
var master = sender.get_masterTableView(); |
var originalSelected = master.get_dataItems()[index].get_selected(); |
if (((args.get_domEvent().target) && (args.get_domEvent().target.type == "checkbox")) |
|| ((args.get_domEvent().srcElement) && (args.get_domEvent().srcElement.type == "checkbox"))) { |
selected[index] = !originalSelected; |
return; |
} |
if (isIE) { |
if (selected[index]) { |
args.set_cancel(true); |
selected[index] = false; |
} |
else { |
selected[index] = !originalSelected; |
} |
clickedItemIndex = index; |
} |
else { |
if (clickedItemIndex == index && !selected[index]) { |
args.set_cancel(true); |
} |
} |
} |
function RowMouseOver(sender, args) { |
if (isIE) { |
clickedItemIndex = args.get_itemIndexHierarchical(); |
} |
} |

<script src="/JS/RadGridSelectionFix.js" type="text/javascript"></script> |
</body> |
if ((typeof (Telerik) != "undefined") && (typeof (Telerik.Web) != "undefined") && (typeof (Telerik.Web.UI) != "undefined") && (typeof (Telerik.Web.UI.RadGrid) != "undefined")) { |
Telerik.Web.UI.RadGrid.prototype._fix_isIE = navigator.appVersion.indexOf("MSIE") > 0; |
Telerik.Web.UI.RadGrid.prototype._fix_selected = new Array(); |
Telerik.Web.UI.RadGrid.prototype._fix_ownSelecting = false; |
Telerik.Web.UI.RadGrid.prototype._fix_clickedItemIndex = ""; |
Telerik.Web.UI.RadGrid.prototype._fix_initialize = Telerik.Web.UI.RadGrid.prototype.initialize; |
Telerik.Web.UI.RadGrid.prototype.initialize = function() { |
this.add_gridCreated(SelFixGridCreated); |
this._fix_initialize(); |
this.add_rowClick(SelFixRowClick); |
this.add_rowDeselecting(SelFixRowDeselecting); |
this.add_rowSelecting(SelFixRowSelecting); |
this.add_rowMouseOver(SelFixRowMouseOver); |
} |
} |
function getItemSelFix(table, itemIndexHierarchical) { |
var items = table.get_dataItems(); |
for (i = 0; i < items.length; i++) { |
if (items[i]._itemIndexHierarchical == itemIndexHierarchical) { |
return items[i]; |
} |
} |
return null; |
} |
function SelFixGridCreated(sender, args) { |
if (!sender.get_allowMultiRowSelection()) { return; } |
var items = sender.get_selectedItemsInternal(); |
if ((items != null) && (items.length > 0)) { |
for (var i = 0; i < items.length; i++) { |
sender._fix_selected[items[i].itemIndex] = true; |
} |
} |
} |
function SelFixRowClick(sender, args) { |
if (!sender.get_allowMultiRowSelection()) { return; } |
if (!sender._fix_isIE) { |
var index = args.get_itemIndexHierarchical(); |
sender._fix_selected[index] = !getItemSelFix(args.get_tableView(), index).get_selected(); |
sender._fix_clickedItemIndex = index; |
getItemSelFix(args.get_tableView(), index).set_selected(!getItemSelFix(args.get_tableView(), index).get_selected()); |
} |
} |
function SelFixRowDeselecting(sender, args) { |
if (!sender.get_allowMultiRowSelection()) { return; } |
var index = args.get_itemIndexHierarchical(); |
if ((sender._fix_ownSelecting) |
|| ((args.get_domEvent().target) && (args.get_domEvent().target.type == "checkbox")) |
|| ((args.get_domEvent().srcElement) && (args.get_domEvent().srcElement.type == "checkbox"))) { |
sender._fix_selected[index] = false; |
return; |
} |
if (sender._fix_clickedItemIndex != index && sender._fix_selected[index]) { |
args.set_cancel(true); |
} |
} |
function SelFixRowSelecting(sender, args) { |
if (!sender.get_allowMultiRowSelection()) { return; } |
var index = args.get_itemIndexHierarchical(); |
var originalSelected = getItemSelFix(args.get_tableView(), index).get_selected(); |
if (((args.get_domEvent().target) && (args.get_domEvent().target.type == "checkbox")) |
|| ((args.get_domEvent().srcElement) && (args.get_domEvent().srcElement.type == "checkbox"))) { |
sender._fix_selected[index] = !originalSelected; |
return; |
} |
if (sender._fix_isIE) { |
if (sender._fix_selected[index]) { |
args.set_cancel(true); |
sender._fix_selected[index] = false; |
} |
else { |
sender._fix_selected[index] = !originalSelected; |
} |
sender._fix_clickedItemIndex = index; |
} |
else { |
if (sender._fix_clickedItemIndex == index && !sender._fix_selected[index]) { |
args.set_cancel(true); |
} |
} |
} |
function SelFixRowMouseOver(sender, args) { |
if (!sender.get_allowMultiRowSelection()) { return; } |
if (sender._fix_isIE) { |
sender._fix_clickedItemIndex = args.get_itemIndexHierarchical(); |
} |
} |

If you select and then deselect the row and then PostBack (or access the grid server-side) the grid it shows the row as checked (does not unselect it). It works correctly if you click the checkbox but clicking the row to deselect does not work.
Any thoughts?

It was more than 4 years ago. Everything has been changed since that time. I surprised that solution provided 4 years ago still works. I propose to take a look at _fix_isIE variable. It may be that IE detection work wrong with IE 9+

The IE detection does work. It seems something wrong with the deselection of the row (shows it as deselected on clientside) but the grid does not lose the value (accessing from server) but the grid does work properly when using the checkboxes.
I'm not expecting Uladzimir to fix it but hopefully someone else has an idea!
You can use the approach suggested in the following post to achieve the requested functionality:
http://www.telerik.com/support/code-library/get-selected-items-through-all-pages#kht8vWCthkS9M1nSFAY8yg
Hope this helps.
Regards,
Eyup
Telerik
Check out the Telerik Platform - the only platform that combines a rich set of UI tools with powerful cloud services to develop web, hybrid and native mobile apps.