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

How does Grid update its dataSource?

2 Answers 951 Views
Grid
This is a migrated thread and some comments may be shown as answers.
ITS
Top achievements
Rank 1
ITS asked on 04 Jul 2013, 08:49 PM
I am using a kendoDropDownList in cell edit mode. User can select the value of the drop down list through keyboard. When they press Enter, the new value is saved back to the dataSource.

From here, two things I am trying to do. One is additional keyboard support for using left and right arrow to submit the new value too. Another one is pressing a key to cycle through all options begin with that key.
Eg. if it's a list about cities in U.S., pressing C will select Cleveland, pressing C again will select Colorado Springs etc.

What I done is hook up a downDown event to the kendoDropDownList during the grid edit event handler.
edit: function (e) {
                    var input = e.container.find('input');
                    var currentValue = input.val();
                    if (e.container.find('.k-dropdown').length > 0) {
                        input = e.container.find('.k-dropdown');
                        currentValue = e.container.find('.k-input').text();
                    }
 
                    input.off('keydown', handleKeyDown);
                    input.on('keydown', null, { input: input, value: currentValue, isDropDownList: (e.container.find('.k-dropdown').length > 0) }, handleKeyDown);
                },
In the event handler, I figured out the next value to select, then I ran a problem. I don't know how to get this value saved back to the dataSource. I tried a couple of ways like.
$(el).find('input').data('kendoDropDownList').select(selectedIndex + 1);
$(el).find('input').data('kendoDropDownList').value(newValue);
$(el[0]).find(".k-input").text(newValue);
In the debugging, I can see kendroDropDownList.value() does give me the newValue. But that is just changed at the drop down list, the underlying dataSource is not changed. so when I do grid.closeCell(), or grid.SaveRow(), the old value is populated back to the drop down list.

There must be a step in between that will make the grid commit changes to its dataSource, please help.

Thank you

2 Answers, 1 is accepted

Sort by
0
Alexander Valchev
Telerik team
answered on 08 Jul 2013, 12:40 PM
Hello,

In order to modify a given field from the DataSource, you should get reference to the corresponding Model (record) and set the new value via set method. In this way the DataSource will be notified for the change and will mark the record as 'dirty'.

You can synchronize the changes with remote service via sync method.

Regards,
Alexander Valchev
Telerik
Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
0
ITS
Top achievements
Rank 1
answered on 14 Jul 2013, 10:46 PM
Base on Alexander's help, here is the code for doing the data source update manually. Scenario here is if you have a grid with cell editing and cell selectable.
There are times when you want to (have to?) save the input value into data source yourself, there are manually to provide additional keyboard support.
For example, enter and tab works out of the box, but up/down/left and right arrow does not have value by default.

Firstly, in Kendo Grid Edit event handler, add our own keydown event handler on the input. Worth to mention is the drop down list,
I can call save while user is navigating between drop down list options, but that is not an expected behavior from the user point of view,
they are likely to select the right option through keyboard up and down arrow, then either press enter/tab or mouse click to move away to another cell,
and that is when we should be calling save.
Key here is to pass in the e.model.uid for identification on the input control. I also pass in the input value, this is the original value used to determine
if the user has made any changes and hence whether we need to call the save or not.
edit: function (e) {
var input = e.container.find('input');
var currentValue = input.val();
if (e.container.find('.k-dropdown').length > 0) {
input = e.container.find('.k-dropdown');
currentValue = e.container.find('.k-input').text();
} else if (e.container.find('textarea').length > 0) {
input = e.container.find('textarea');
currentValue = input.val();
input.select();
} else {
// Select existing cell value, so user can easily type the new value.
input.select();
}
 
input.off('keydown', handleKeyDown);
input.on('keydown', null, { input: input, value: currentValue, uid: e.model.uid, isDropDownList: (e.container.find('.k-dropdown').length > 0), isTextArea: (e.container.find('textarea').length > 0) }, handleKeyDown);
 
if (e.container.find('.k-dropdown').length > 0) {
input.off('blur', handleBlur);
input.on('blur', null, { input: input, value: currentValue, uid: e.model.uid, isDropDownList: true }, handleBlur);
}
},
HandleKeyDown and handleBlur are similar code. Here we do the saving. Note if you need to update multiple values, you can use 
dataItem.name1 = value1;
dataItem.name2 = value2;
Then you have to call grid.data('kendoGrid').dataSource.sync(), in my case, i didnt have to call sync here, maybe it's been called by my code somewhere else.
var handleKeyDown = function (e) {
// srcElement does not work in FF
var el = (typeof e.srcElement === "undefined") ? $(e.target) : $(e.srcElement);
var value = (e.data.isDropDownList) ? $(el).find('input').val() : el.val();
var tabKey = 9;
var enterKey = 13;
var leftArrowKey = 37;
var upArrowKey = 38;
var rightArrowKey = 39;
var downArrowKey = 40;
var grid = $('#grid');
var controlName = (e.data.isDropDownList) ? $(el).find('input')[0].name : $(el)[0].name;
 
// Skip up and down arrow when the control is a drop down list.
if (e.data.isDropDownList && (e.which == downArrowKey || e.which == upArrowKey)) {
e.stopImmediatePropagation();
return;
}
 
             
switch (e.which) {
case tabKey:
case enterKey:
case leftArrowKey:
case upArrowKey:
case rightArrowKey:
case downArrowKey:
                     
// If it's a drop down list (and it wont be when user press up/down key,
// that is handled earlier already), and the user is navigating away,
// we need to update the data source ourselves, so the postback can be triggered.
if (value != e.data.value && (e.data.isDropDownList || e.data.isTextArea)) {
var dataItem = grid.data('kendoGrid').dataSource.getByUid(e.data.uid);
dataItem.set(controlName, value);
}
}
};
I hope this will be helpful to someone.
Tags
Grid
Asked by
ITS
Top achievements
Rank 1
Answers by
Alexander Valchev
Telerik team
ITS
Top achievements
Rank 1
Share this question
or