Ok
simple create a new row with null values, and add the editor as a ComboBox with the edit field.
Editable:inline
Click Combo show, populates, select, click away from the cell, cell shows [object object]
the data is {Id=1, ColumnName="blah", datatype="blah"}
I have tried all examples for the past two weeks and none seem to work.
Should be easy right? OK I give up.
BTW, all the combobox behave the same.
Any help would be appreciated.
var grid = $("#grid").kendoGrid({
width: 500,
dataSource: {
transport: {
read: {
url: "Grid/GetSearches",
dataType: "json",
},
update: {
url: "Grid/UpdateSearches",
dataType: "json",
},
create: {
url: "Grid/CreateSearches",
dataType: "json",
},
destroy: {
url: "Grid/DeleteSearches",
dataType: "json",
}
},
schema: {
data: function (data) {
return data.data;
},
total: function (data) {
return data.total;
},
model: {
id: "Id",
fields: {
Id: { type: "number", editable: false },
field: {
ColumnName: { type: "string" },
Criteria: { type: "string" },
Value: { type: "string" },
Predicate: { type: "string" }
}
}
}
},
cancel: function (e) {
},
},
scrollable: false,
pageable: false,
editable: {
createAt:"bottom",
},
toolbar: ["create","save", "cancel"],
columns: [
{
field: "Id",
readonly: true,
width: 25,
},
{
field: "ColumnName",
width: 200,
editor: function (container, options) {
$('<input data-bind="value:' + options.field + '" />')
.appendTo(container)
.kendoComboBox({
dataTextField: "ColumnName",
dataValueField: "ColumnName",
autoBind: false,
dataSource: typesds
});
}
},
{ field: "Criteria", width: 200, editor: criteriaDropDownEditor},
{ field: "Value", width: 200, editor: textEditor },
{
field: "Predicate",
width: 200,
template: "#=generateTemplate(Id)#",
editor: function (container, options) {
$('<input required id="Id" style="width:200px;" Name="' + options.field + '" />')
.appendTo(container)
.kendoDropDownList({
autoBind: false,
dataTextField: "Predicate",
dataValueField: "Id",
change: function(e)
{
selectedValue = this.text();
},
dataSource: {
data: [
{ Id: 1, Predicate: " " },
{ Id: 1, Predicate: "And" },
{ Id: 2, Predicate: "Or" },
]
},
});
}
},
{ command: [{ className: "bt-add", name: "addRow", text: "Add Row" }] },
{ command: [{ className: "bt-del", name: "delRow", text: "Delete Row" }] },
]
}).data("kendoGrid");
var typesds = new kendo.data.DataSource({
transport: {
read: {
url: "Grid/GetFieldList",
dataType: "json",
type: "POST",
},
},
schema: {
data: function (data) {
return data.data;
},
total: function (data) {
return data.total;
},
model: {
id: "Id",
fields: {
Id: { type: "number", readonly: true },
ColumnName: { type: "string" },
DataType: { type: "string" }
}
}
},
});
6 Answers, 1 is accepted
Thank you for the provided Kendo UI Grid declaration. It helped me in troubleshooting the issue.
I have noticed that in the schema.model object of the grid's data source, the specified type is "string". While the return type of the custom editor is an object. When the .toString() method is called over an object it returns the type - in this case [object] [object]. In order to overcome this issue, set the field property of the column to an object and set a template to visualize the data after clicking away from the cell.
The Grid / Editing custom editor live demo exposes how this could be done. Take into closer details the Category column of the grid which has a combo box for an editor:
https://demos.telerik.com/kendo-ui/grid/editing-custom
If you need assistance with implementing the aforementioned suggestion, feel free to get back to me.
Kind regards,
Tsvetomir
Progress Telerik

Thanks for the review. However, after this change over it is now coming as undefined.
I can not find an event that allows for the validation of the data being passed in after the cell is updated.
Populating the ComboBox without the field.ColumnName causes a failure.
THanks
$(document).ready(function () {
var textEditor = function (container, options) {
$('<input data-value-update="input" style="width:200px;" data-bind="value:' + options.field + '"/>')
.appendTo(container);
};
var typesds = new kendo.data.DataSource({
transport: {
read: {
url: "Grid/GetFieldList",
dataType: "json",
type: "POST",
},
},
schema: {
data: function (data) {
return data.data;
},
total: function (data) {
return data.total;
},
model: {
id: "id",
fields: {
TableId: {type: "int"},
Id: { type: "number", readonly: true },
Column: { type: "string" },
DataType: { type: "string" }
}
}
},
});
function fieldDropDownEditor(container, options) {
$('<input required data-text-field="ColumnName" data-value-field="ColumnName" style="width:200px;" data-bind="value:' + options.field + '" />')
.appendTo(container)
.kendoComboBox({
dataTextField: ColumnName,
dataValueField: ColumnName,
autoBind: false,
dataSource:typeds,
});
}
function criteriaDropDownEditor(container, options) {
$('<input required data-text-field="Criteria" data-value-field="Id" style="width:200px;" data-bind="value:' + options.field + '" />')
.appendTo(container)
.kendoComboBox({
autoBind: false,
dataSource: {
data: [
{ Id: 1, Criteria: "Equal to" },
{ Id: 2, Criteria: "Greater than" },
{ Id: 3, Criteria: "Greater than Equal to" },
{ Id: 4, Criteria: "Less than" },
{ Id: 5, Criteria: "Less than Equal to" },
{ Id: 6, Criteria: "Starts With" },
{ Id: 7, Criteria: "Ends With" },
{ Id: 8, Criteria: "Contains" },
{ Id: 9, Criteria: "Is Empty" },
]
}
});
}
var grid = $("#grid").kendoGrid({
width: 500,
dataSource: {
transport: {
read: {
url: "Grid/GetSearches",
dataType: "json",
},
update: {
url: "Grid/UpdateSearches",
dataType: "json",
},
create: {
url: "Grid/CreateSearches",
dataType: "json",
},
destroy: {
url: "Grid/DeleteSearches",
dataType: "json",
}
},
schema: {
data: function (data) {
return data.data;
},
total: function (data) {
return data.total;
},
model: {
id: "Id",
fields: {
Id: { type: "number", editable: false },
field: {
Column: {
defaultValue: {Id:1, ColumnName:"DA Module"} },
Criteria: { type: "string" },
Value: { type: "string" },
Predicate: { type: "string" }
}
}
}
},
cancel: function (e) {
},
},
scrollable: false,
pageable: false,
editable: {
createAt:"bottom",
},
edit: function (e) {
},
toolbar: ["create","save", "cancel"],
columns: [
{
field: "Id",
readonly: true,
width: 25,
},
{
field: "Column",
width: 200,
template: "#=field.ColumnName#",
editor: function (container, options) {
$('<input Name="' + options.field + '" />')
.appendTo(container)
.kendoComboBox({
dataTextField: "field.ColumnName",
dataValueField: "field.Id",
autoBind: false,
dataSource: typesds
});
}
},
{ field: "Criteria", width: 200, editor: criteriaDropDownEditor},
{ field: "Value", width: 200, editor: textEditor },
{
field: "Predicate",
width: 200,
template: "#=generateTemplate(Id)#",
editor: function (container, options) {
$('<input required id="Id" style="width:200px;" Name="' + options.field + '" />')
.appendTo(container)
.kendoDropDownList({
autoBind: false,
dataTextField: "Predicate",
dataValueField: "Id",
change: function(e)
{
selectedValue = this.text();
},
dataSource: {
data: [
{ Id: 1, Predicate: " " },
{ Id: 1, Predicate: "And" },
{ Id: 2, Predicate: "Or" },
]
},
});
}
},
{ command: [{ className: "bt-add", name: "addRow", text: "Add Row" }] },
{ command: [{ className: "bt-del", name: "delRow", text: "Delete Row" }] },
]
}).data("kendoGrid");
Based on the provided declaration of the modified grid, I have observed that the field definition for the "Column" set through the DataSource schema is configured as "string". Passing an object while the grid is configured to expect string might lead to unexpected behavior. Here is a sample Dojo project with a Kendo UI DropDownList widget as an editor.
https://dojo.telerik.com/EreXoDUL
Take a look at the sample and find out what are the crucial differences compared to the project on your side.
As for the validation that you want to perform, you can handle the "save" event of the Grid and use "e.preventDefault()" to prevent the change, but the cell will be closed even if the method is called, so it might not be what you need. What I could suggest is to implement custom validation rule as shown in the following online demo:
If further assistance is needed, feel free to contact us again.
Kind regards,
Tsvetomir
Progress Telerik

I am even more confused now than before.
In the example, there is no data item, therefore no way to save, the category data.
the aim here is to simply be able to create a search using a set of column names (plus their IDs) with the criteria and predicates with a value to compare.
There is no simple example of just pulling this data and using the grid to select it.
Where in the example is the Category data saved if it is not part of the datasource?
Thank you.

var grid = $("#grid").kendoGrid({
width: 500,
autoBind:true,
dataSource: {
transport: {
read: {
url: "Grid/GetSearches",
dataType: "json",
},
update: {
url: "Grid/UpdateSearches",
dataType: "json",
},
create: {
url: "Grid/CreateSearches",
dataType: "json",
},
destroy: {
url: "Grid/DeleteSearches",
dataType: "json",
}
},
schema: {
data: function (data) {
return data.data;
},
total: function (data) {
return data.total;
},
model: {
id: "Id",
fields: {
Id: { type: "number", editable: false },
field: {
Column: {
defaultValue: {Id:312, ColumnName:"Bolted"} },
Criteria: { defaultValue: { Id: 1, ColumnName: "Equal To" } },
Value: { type: "string" },
Predicate: { defaultValue: { Id: 1, ColumnName: " " } }
}
}
}
},
cancel: function (e) {
},
},
scrollable: false,
pageable: false,
editable: {
createAt:"bottom",
},
edit: function (e) {
if (e.model.isNew()) {
e.dataItem = e.dataSource.pushCreate();
}
},
toolbar: ["create","save", "cancel"],
columns: [
{
field: "Id",
readonly: true,
width: 25,
},
{
field: "Column",
width: 200,
template: "#=generateTemplate(Id)#",
editor: function (container, options) {
$('<input Name="' + options.field + '" />')
.appendTo(container)
.kendoComboBox({
dataTextField: "field.ColumnName",
dataValueField: "field.Id",
change: function (e) {
selectedValue = this.text();
},
autoBind: false,
dataSource: typesds
});
}
},
{
field: "Criteria", width: 200, template: "#=generateTemplate(Id)#", editor: function(container, options) {
$('<input Name:"' + options.field + '" />')
.appendTo(container)
.kendoComboBox({
autoBind: false,
dataTextField: "Criteria",
dataValueField: "Id",
change: function (e) {
selectedValue = this.text();
},
dataSource: {
data: [
{ Id: 1, Criteria: "Equal to" },
{ Id: 2, Criteria: "Greater than" },
{ Id: 3, Criteria: "Greater than Equal to" },
{ Id: 4, Criteria: "Less than" },
{ Id: 5, Criteria: "Less than Equal to" },
{ Id: 6, Criteria: "Starts With" },
{ Id: 7, Criteria: "Ends With" },
{ Id: 8, Criteria: "Contains" },
{ Id: 9, Criteria: "Is Empty" },
]
}
});
}},
{ field: "Value", width: 200, editor: textEditor },
{
field: "Predicate",
width: 200,
template: "#=generateTemplate(Id)#",
editor: function (container, options) {
$('<input style="width:200px;" Name="' + options.field + '" />')
.appendTo(container)
.kendoDropDownList({
autoBind: false,
dataTextField: "Predicate",
dataValueField: "Id",
change: function(e)
{
selectedValue = this.text();
},
dataSource: {
data: [
{ Id: 1, Predicate: " " },
{ Id: 1, Predicate: "And" },
{ Id: 2, Predicate: "Or" },
]
},
});
}
},
{ command: [{ className: "bt-add", name: "addRow", text: "Add Row" }] },
{ command: [{ className: "bt-del", name: "delRow", text: "Delete Row" }] },
]
}).data("kendoGrid");
grid.table.kendoSortable({
hint: hintElement,
cursor: "move",
placeholder: function (element) {
return element.clone().addClass("k-state-hover").css("opacity", 0.65);
},
container: "#grid tbody",
filter: ">tbody >tr",
cancel: function (e) {
alert();
},
change: function (e) {
var grid = $("#grid").data("kendoGrid"),
oldIndex = e.oldIndex, // The old position
newIndex = e.newIndex, // The new position
view = grid.dataSource.view(),
dataItem = grid.dataSource.getByUid(e.item.data("uid")); // Retrieve the moved dataItem
grid.dataSource.remove(dataItem);
grid.dataSource.insert(newIndex, dataItem);
//dataItem.Id = newIndex; // Update the order
//dataItem.dirty = true;
//// Shift the order of the records
//if (oldIndex < newIndex) {
// for (var i = oldIndex + 1; i <= newIndex; i++) {
// view[i].Order--;
// view[i].dirty = true;
// }
//} else {
// for (var i = oldIndex - 1; i >= newIndex; i--) {
// view[i].Order++;
// view[i].dirty = true;
// }
//}
//grid.dataSource.sync();
}
});
});
I have noticed that in the editors you have provided, the name attribute of the input elements are spelled with a capital "N" letter and are not consistent. Some of the attributes are followed by a "=" and others by a colon. The Kendo UI widgets highly depend on this attribute since they are bound by name.
Furthermore, the undefined value comes from the generateTemplate() function. I am not aware of what does exactly the function consist of. Could you share the code of interest?
Also, in order to make the communication more efficient and to provide a clear-cut answer, I recommend you to create a runnable sample in which the issue could be replicated. You can use dummy data, following the initial data you have on your side. This would allow me to debug the sample project locally and discover where does the issue stem from.
Ideally, share your code sample as a Dojo project:
https://dojo.telerik.com/IYeWOHak
Modify the name attribute and see if this would make a difference. I am looking forward to you sharing a sample project isolating the specific issue.
Kind regards,
Tsvetomir
Progress Telerik