Hello,
I am using columns.Select() to make my rows selectable via checkboxes.
I would like to know if it is possible to use the shift key to select multiple rows as in:
1) click the checkbox for the first row to be selected.
2) hold the shift key down
3) click the checkbox for the last row to be selected.
4) programmatically select the entire range of rows between the two selected rows.
Are there any demos that relate to this functionality?
Thanks,
Ryan
7 Answers, 1 is accepted
A possible solution is to attach a click event handler to the checkbox and within that handler check whether the shift key is pressed and if it is select the range between the lastly selected row and the currently selected.
e.g.
$(
function
() {
var
lastActive;
$(
'#grid'
).on(
'click'
,
"tbody > tr input[data-role='checkbox'].k-checkbox"
,
function
(e) {
var
grid = $(
'#grid'
).data(
'kendoGrid'
);
if
(e.shiftKey) {
if
(!lastActive) {
return
;
}
grid.clearSelection();
var
allRows = grid.items();
var
start = allRows.get().indexOf(lastActive.get()[0])
var
end = allRows.get().indexOf($(e.target).parents(
'tr'
).get()[0]);
grid.select(allRows.splice(start, end - start+1));
}
else
{
lastActive = $(e.target).parents(
'tr'
);
}
})
})
For your convenience I am attaching a small sample which demonstrates the above approach.
Regards,
Georgi
Progress Telerik

Hello Georgi,
Thank you for this post. Sorry it took me a little time to try this out, but I have now given it a try, and it is working wonderfully! This is a big relief, as this feature is actually very important to our users.
Regards,
Ryan

Hi Georgi,
I have made a few modifications to your sample code, and am having one problem.
- The first modification is to allow a range of rows to be selected when "end" is less than "start" (i.e. allow the selection to grow upwards, not just downwards on the grid). This is working fine.
- Second, in order make the grid behave more like a multiselect list box, I added code to clear any previously selected rows unless the control key or shift key is pressed.
$(function () {
var lastActive;
$('#auto_gen_conn_mngr_grid').on('click', "tbody > tr input[data-role='checkbox'].k-checkbox", function (e) {
var grid = $("#auto_gen_conn_mngr_grid").data("kendoGrid");
var allRows = grid.items();
if (e.shiftKey) {
if (!lastActive) {
return;
}
var start = allRows.get().indexOf(lastActive.get()[0]);
var end = allRows.get().indexOf($(e.target).parents('tr').get()[0]);
if (end < start) {
var tmp = start;
start = end;
end = tmp;
}
grid.select(allRows.splice(start, end - start + 1));
} else {
lastActive = $(e.target).parents('tr');
if (!e.ctrlKey) {
grid.clearSelection();
}
var row = allRows.get().indexOf($(e.target).parents('tr').get()[0]);
grid.select(row);
}
});
});

The above post was not complete when I accidentally submitted it...
.....Second, in order make the grid behave more like a multiselect list box, I added code to clear any previously selected rows unless the control key or shift key is pressed.
This is also working, HOWEVER, now if I clear the selection due to the CTRL key not being pressed, the code to reselect the current row is not working. So I have to hold CTRL to select a single row, which is not what I want. I have looked at the code under the debugger, and the row index is correct. Is there any reason why grid.select(..) following grid.clearSelection(..) would not be working? Please see the code in the "else" block above.
Thanks,
Ryan
I have debugged the modified version of the code and noticed that in the else statement the row variable is actually the index of the row - not the row itself.
You should modify the logic as follows to pass the row to the select method - not the index:
$(
function
() {
var
lastActive;
$(
'#grid'
).on(
'click'
,
"tbody > tr input[data-role='checkbox'].k-checkbox"
,
function
(e) {
debugger
var
grid = $(
"#grid"
).data(
"kendoGrid"
);
var
allRows = grid.items();
if
(e.shiftKey) {
if
(!lastActive) {
return
;
}
var
start = allRows.get().indexOf(lastActive.get()[0]);
var
end = allRows.get().indexOf($(e.target).parents(
'tr'
).get()[0]);
if
(end < start) {
var
tmp = start;
start = end;
end = tmp;
}
grid.select(allRows.splice(start, end - start + 1));
}
else
{
lastActive = $(e.target).parents(
'tr'
);
if
(!e.ctrlKey) {
grid.clearSelection();
}
var
row = allRows.eq(allRows.get().indexOf($(e.target).parents(
'tr'
).get()[0]));
grid.select(row);
}
});
});
Regards,
Georgi
Progress Telerik

Can we do the same thing with kendo Multi-select with value mapper? i am using the kendo multi-select with more than 1000 rows with value mapper page size 80. when i am trying to select rows with Shift+ arrowdown key then after 80 rows it is not working and giving wrong selected items in Tagmode.single. I want below thing in multiselect.
1) click the checkbox for the first row to be selected.
2) hold the shift key down
3) click the checkbox for the last row to be selected.
4) programmatically select the entire range of rows between the two selected rows.
Please find my code:
@(Html.Kendo().MultiSelect()
.Name("ddlTagAccelerometer")
.HtmlAttributes(new { style = "width:100%" })
.DataTextField("text")
.Placeholder("Please select sensor...")
.DataValueField("value")
.AutoBind(false)
.TagMode(TagMode.Single)
.Enable(false)
.AutoClose(false)
.Filter(FilterType.Contains)
.ItemTemplate("<input type='checkbox' class='multiselectcheckbox'/> #:data.text#")
.FooterTemplate("Total <strong>#: instance.dataSource.total() #</strong> items found")
.TagTemplateId("tagTemplate")
.Events(e => e.Change("changeMultiselect").DataBound("dataBoundMultiselect").Select("onMultiselect"))
.DataSource(source =>
{
source.Custom()
.ServerFiltering(true)
.ServerPaging(true)
.PageSize(80)
.Type("aspnetmvc-ajax")
.Transport(transport =>
{
transport.Read(read =>
{
read.Action("GetTagAccelerometer", "Home").Data("facilityData");
});
})
.Schema(schema =>
{
schema.Data("Data").Total("Total");
});
})
.Height(520).Virtual(v => v.ItemHeight(32).ValueMapper("valueMapperTagAccelerometer"))
)
Hi Pankaj,
I am afraid using the same approach on a MultiSelect widget with virtualization enabled would not be possible. The reason is the elements and the data items in the widget are virtualized. That means different items will use the same DOM element depending on the exact scroll position. On the other hand, there will be cases when not all intermediate items will be present in the widget DataSource. That will make their selection impossible.
As a side note, in case you have any further questions on a different widget, which was not part of the original question (e.g. the Grid), I would recommend you to open a separate thread for that. This way we will be able to keep each thread focused.
Regards,
Veselin Tsvetanov
Progress Telerik
Our thoughts here at Progress are with those affected by the outbreak.