It seems that changed values in fields are not retained if the grid has inline editing enabled and a sortable widget created on it. Here's a quick demo:
http://trykendoui.telerik.com/eYUJ
The only way to save values is to tab out of the field, rather than clicking somewhere else. If the sortable widget is not created it's fine, though.
I've been able to reproduce this with both the official Q1 release and the latest internal build (2014.1.409). Is this a known issue?
Thanks,
Nick
17 Answers, 1 is accepted
Thank you for getting in touch with us.
I was able to reproduce the issue and can confirm that this is a problem on our side but we will need more time to investigate this issue. I will write you back as soon as I have more information, most probably tomorrow.
Regards,
Alexander Valchev
Telerik
I am using version "2014.1.415" and this issue still persist,
Additionally if you have Destroy event set to the grid, and do some data shuffling and save grid changes,
.Destroy(Sub(oDestroy) oDestroy.Action("DeleteData", "Common")) _
grid saveChanges() method would make a call to both update as well as destroy event.
var oGrid = $("#gdDataList").data("kendoGrid");
oGrid.saveChanges();
Any idea how to fix this?
Thanks,
Eric
Regarding problem with editing and non-updating values:
The problem comes from the fact that drag'n'drop components used by Sortable widget prevent the mousedown event. As a result the editor input element is not blurred, respectively its change event does not fire and the MVVM does not update the dataSource value. I am afraid that at present this behavior cannot be prevented, there is a possible workaround however it requires a little bit extra coding.
In order to get the scenario working, the developer have to force the MVVM to update the value when the 'unput' event fires. That can be done by attaching a data-value-update="input" attribute to the editor. In order to that you have to create custom editor for every column. For example:
columns: [
{ field:
"ProductName"
, editor: productNameEditor },
{ field:
"UnitPrice"
, title:
"Unit Price"
, format:
"{0:c}"
, width:
"130px"
},
{ field:
"UnitsInStock"
, title:
"Units In Stock"
, width:
"130px"
},
{ field:
"Discontinued"
, width:
"130px"
}
],
function
productNameEditor(container, options) {
$(
'<input required class="k-input k-textbox" data-bind="value:'
+ options.field +
'" data-value-update="input" />'
).appendTo(container);
}
Regarding your second question about the destroy command.
I am not sure what causes the problem. Generally speaking the update transport will be triggered if there are unsaved modifications over existing dataItems and the destroy transport - if there are items to be deleted. Usually problems related to issues with submitting the changes are related to dataSource.schema definition and more specifically the model ID. Please verify that you have specified the model ID and that each existing data Model has unique ID. In case this does not help please open a new support ticket and provide the needed details (sample/code snippets) that will help us understand the exact scenario and assist you further. Thank you in advance for the understanding.
Regards,
Alexander Valchev
Telerik
Can you get ASP.Net example on how to implement editor,
I could only find .EditorTemplateName, and I don't see any difference,
2 -
I have the sortable change event setup to this little js function below, and has datasource insert and update done in the end,
I am thinking if that might have something to do with it,
function gdFormTab_Change(e) {
var grid = $("#gdFormTab").data("kendoGrid"),
skip = grid.dataSource.skip(),
oldIndex = e.oldIndex + skip,
newIndex = e.newIndex + skip,
data = grid.dataSource.data(),
dataItem = grid.dataSource.getByUid(e.item.data("uid"));
grid.dataSource.remove(dataItem);
grid.dataSource.insert(e.newIndex, dataItem);
}
Thanks,
Eric
Regarding your questions:
1. Please check this help topic as it explains how to create custom editors in ASP.NET MVC wrappers. Basically all you need to do is attaching a data-value-update="input" attribute to the editor input.
2. What exactly bothers you in the change event handler? What makes you think that you made an error?
Generally speaking the code does not take into account the paging. Note the difference from the same code used in the demo page:
function
gdFormTab_Change(e) {
var
grid = $(
"#gdFormTab"
).data(
"kendoGrid"
),
skip = grid.dataSource.skip(),
oldIndex = e.oldIndex + skip,
newIndex
= e.newIndex + skip,
data = grid.dataSource.data(),
dataItem = grid.dataSource.getByUid(e.item.data(
"uid"
));
grid.dataSource.remove(dataItem);
grid.dataSource.insert(
e.
newIndex, dataItem);
//e.newIndex does
not
include the skip,
newIndex
does
}
The code above aims to reorder the dataItems in the dataSource.
Regards,
Alexander Valchev
Telerik
Here's a simpler work around. I really didn't want to go and add a custom template everywhere. Also, this only seems to affect IE and not Chrome or any other browser.
$(document).ready(function () {
// Work to lock editing cells
$("form").submit(function () {
// If we have anything that is being edited
if ($("td.k-edit-cell").length > 0) {
// Grab the active element per Kendo
var activeElement = kendo._activeElement();
// If that element is defined and is not the document body
if ((activeElement) && (activeElement.nodeName.toLowerCase() !== "body")) {
// Blur it manually, and also close the cell.
$(activeElement).blur();
$("#grid").data("kendoGrid").closeCell()
}
}
});
});
Try to add them using HtmlAttributes() method.
Regards,
Alexander Valchev
Telerik
Hi Alexander,
thanks a lot for providing the workaround (using custom editor) - it does work perfectly fine for 'simple' editors.
However, I'm unable to fix the issue for columns where a widget (e.g. numericTextBox) is used - see the 'Units in Stock' column here. Clicking into a cell of the 'Units in Stock' column, then changing a value, and then clicking another cell within the grid causes the cell to lose its new value. (drag & drop sorting is a required functionality here)
Would you (or somebody from your team) be able to assist and provide a solution/workaround?
Thanks,
Julian
Hi Alexander,
thanks a lot for providing the workaround (using custom editor) - it does work perfectly fine for 'simple' editors.
However, I'm unable to fix the issue for columns where a widget (e.g. numericTextBox) is used - see the 'Units in Stock' column here. Clicking into a cell of the 'Units in Stock' column, then changing a value, and then clicking another cell within the grid causes the cell to lose its new value. (drag & drop sorting is a required functionality here)
Would you (or somebody from your team) be able to assist and provide a solution/workaround?
Thanks,
Julian
Using the combination of Kendo UI Grid with "incell" editing, Kendo UI Sortable, and a widget as a column editor is a known limitation of Kendo UI:
http://docs.telerik.com/kendo-ui/framework/mvvm/bindings/value#control-upon-view-model-update
I can suggest using the two other available options for Grid editing which are "inline" and "popup":
http://docs.telerik.com/kendo-ui/api/javascript/ui/grid#configuration-editable
Please check the information on how to use an editable Grid with the Sortable widget:
http://docs.telerik.com/kendo-ui/controls/interactivity/sortable/integration#sortable-and-editable-grid
I hope this is helpful.
Regards,
Stefan
Telerik by Progress
In case it helps anybody else, I bypassed this limitation by extending the widget's destroy function:
editor:
function
(container, options) {
var
h = $(
"<input data-bind='value:"
+ options.field +
"'/>"
).appendTo(container);
var
inp = h.kendoNumericTextBox({
decimals: 0,
min: 0,
format:
"{0:n0}"
}).data().kendoNumericTextBox;
(
function
(destroy) {
inp.destroy =
function
() {
var
item = $(inp.element).closest(
".k-grid"
).data().kendoGrid.dataItem(
this
.element.closest(
"tr"
));
// Parse the widget value
var
inpVal = +
this
.element.val();
item.set(options.field, inpVal);
destroy.call(
this
);
};
}(inp.des
Ugh... copy/paste fail... and no edit post? Missed the last few characters
editor:
function
(container, options) {
var
h = $(
"<input data-bind='value:"
+ options.field +
"'/>"
).appendTo(container);
var
inp = h.kendoNumericTextBox({
decimals: 0,
min: 0,
format:
"{0:n0}"
}).data().kendoNumericTextBox;
(
function
(destroy) {
inp.destroy =
function
() {
var
item = $(inp.element).closest(
".k-grid"
).data().kendoGrid.dataItem(
this
.element.closest(
"tr"
));
// Parse the widget value
var
inpVal = +
this
.element.val();
item.set(options.field, inpVal);
destroy.call(
this
);
};
}(inp.destroy));
I give up. Previous version. Use options.model to get the item:
var
item = options.model;
$(document).ready(function () {
// Work to lock editing cells
$("body").on("mousedown",".k-grid tr td",function(){
if ($("td.k-edit-cell").length > 0) {
// Grab the active element per Kendo
var activeElement = kendo._activeElement();
// If that element is defined and is not the document body
if ((activeElement) && (activeElement.nodeName.toLowerCase() !== "body")) {
// Blur it manually, and also close the cell.
$(activeElement).blur();
$("td.k-edit-cell").closest(".k-grid").data("kendoGrid").closeCell();
}
}
});
});
I would like to ask if this limitation still exist with the latest kendo version ?
Hello Ivailo,
Yes, here is the same sample with a recent working version:
http://dojo.telerik.com/etIFoQiw/2
Regards,
Eyup
Progress Telerik
Five days of Blazor, Angular, React, and Xamarin experts live-coding on twitch.tv/CodeItLive, special prizes, and more, for FREE?! Register now for DevReach 2.0(20).