How to avoid duplicate entry in Grid / Inline editing?
I am used MVC 4 With Eazor.
Thanks,
Quest
9 Answers, 1 is accepted
We are not sure what you mean by duplicate. Could you please clarify? Generally speaking you can implement a custom validator to perform any non-standard validation.
Greetings,Atanas Korchev
the Telerik team
Please check attached screenshot.
Thanks,
Quest
Thank you for the clarification. I understand now what you need.
Currently Kendo Grid does not provide any built-in feature which would prevent such cases. Perhaps this can be implemented using custom validation. Here is a forum thread discussion custom validation in the context of grid editing. This thread may also be interesting to you.
Atanas Korchev
the Telerik team
I use custom validation on the schema field:
Name: {
editable:
true
,
type:
"string"
,
validation: {
required:
true
,
duplicate:
function
(input) {
if
(input.is(
"[name='Name']"
) && input.val() !=
""
) {
// 1. get data
var
name = input.val();
var
data = $(
"#personnel_screen_grid"
).data().kendoGrid.dataSource.view()
// 2. check for duplicate
var
valid =
true
;
for
(
var
i = 0; i < data.length; i++) {
if
(name == data[i].Name) {
valid =
false
;
input.attr(
"data-duplicate-msg"
,
"Duplicates not allowed."
);
break
;
}
}
return
valid;
}
return
true
;
},
},
},
I forgot to check for a ID when you're adding a new row:
Name: {
editable:
true
,
type:
"string"
,
validation: {
required:
true
,
duplicate:
function
(input) {
if
(input.is(
"[name='Name']"
) && input.val() !=
""
) {
// 1. get data
var
name = input.val();
var
data = $(
"#personnel_screen_grid"
).data().kendoGrid.dataSource.view()
console.log(JSON.stringify(data));
// 2. check for duplicate
var
valid =
true
;
for
(
var
i = 0; i < data.length; i++) {
if
((name == data[i].Name) && data[i]._id) {
valid =
false
;
input.attr(
"data-duplicate-msg"
,
"Duplicates not allowed."
);
break
;
}
}
return
valid;
}
return
true
;
},
},
},
You could not edit the current row name with the last code. I fixed that here:
Name: {
editable:
true
,
type:
"string"
,
validation: {
required:
true
,
duplicate:
function
(input) {
if
(input.is(
"[name='Name']"
) && input.val() !=
""
) {
// 1. get data
var
name = input.val();
var
grid = $(
"#personnel_screen_grid"
).data(
'kendoGrid'
);
var
view = grid.dataSource.view();
var
dataItem = grid.dataItem(grid.current().closest(
"tr"
));
var
name_edit = dataItem.Name;
// 2. check for duplicate
var
valid =
true
;
for
(
var
i = 0; i < view.length; i++) {
if
((name == view[i].Name) && (name != name_edit) && view[i].id) {
valid =
false
;
input.attr(
"data-duplicate-msg"
,
"Duplicates not allowed."
);
break
;
}
}
return
valid;
}
return
true
;
},
},
},
Hi Robert,
I tried this code to get a current row:
but it through an exception: Uncaught TypeError: grid.current is not a function
var
name = input.val();
var
grid = $scope.mainGridOptions;
var
data = grid.dataSource.view();
var
dataItem = grid.dataSource(grid.current().closest(
"tr"
));
console.log(dataItem);
Hello,
I've figured it out.
thank you
I have achieved this by doing the following
var name = input.val();
var grid = $("#grid").data('kendoGrid');
var view = grid.dataSource.view();
var dataItem = grid.dataItem(input.closest("tr"));
duplicate: function (input) {
if (input.is("[name='name']")) {
var name = input.val();
var grid = $("#grid").data('kendoGrid');
var parentid = grid._data.filter(x => x.id == e.data.id)[0];
var parentIndex = grid._data.map(function (img) { return img.id; }).indexOf(parentid.id);
var view = grid._data[parentIndex].childs;
var valid = true;
for (var i = 1; i < view.length; i++) {
if ((name == view[i].name)) {
valid = false;
input.attr("data-duplicate-msg", "Duplicates not allowed.");
break;
}
}
return valid;
}
return true;
}
I have tried this but its checking the row currently being edited and hence returns error. any suggestions in this?
Hi, Anthar, in order to take the data item for the edited child grid, you could access first the grid and after that the data item:
var grid = $(input).closest("[data-role='grid']").getKendoGrid();
var editable = grid.editable.options.model;
Is it possible for you to share what the exact error is? And, is there a need for the logic that checks the duplicate to be adjusted according to your requirement? If yes, share more details on the expected output.
To reuse the same function for the duplicate validation, you could extract the function outside and only pass the id and grid instance. Parent Grid:
duplicate: function (input) {
return validateDuplicate(input, $("#grid").getKendoGrid());
}
For the child grid, you should first save the instance within the edit event:
edit:function(e){
childGrid = e.sender;
},
// ...
duplicate: function (input) {
return validateDuplicate(input, childGrid);
}
Check out the modified version here:
https://dojo.telerik.com/iTUkUkiF
Hi, indeed, it is possible to limit the user from editing specific columns. There are two options:
https://docs.telerik.com/kendo-ui/api/javascript/ui/grid/configuration/columns.editable
The other option is to make the field in the model of the data source non-editable:
https://docs.telerik.com/kendo-ui/api/javascript/data/datasource/configuration/schema#schemamodel
As per the duplicate row with copying the child elements, it is possible, however, the child elements are actually part a separate grid. The master row and the rows inside the detail rows are part of different grids. Hence, you should manually access the first child grid and the child grid of the newly created row and feed the data there.
Note that the new child grid will not be created until the row is expanded at least once. You should expand the row after you add it and only after the child grid is initialized - populate it with the data from the first row.