Hi,
I am experimenting with this grid control.
I have this code where I am filling a grid with data from the SQL table. The data is loading good.
Second step : I want to edit the row and in this case , I want to edit City column which will be a dropdown in edit mode. I have the code to pull the data from database. My API is returning cities. I can see it in console.log. However, the dropdown in the edit mode does not show any data. It is blank. I am not sure where to fix it or how to fix it.
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
<script src="https://code.jquery.com/jquery-1.12.3.min.js"></script>
<link href="https://kendo.cdn.telerik.com/themes/12.0.0/default/default-main.css" rel="stylesheet" />
<!-- Add the Kendo library by either using the JAVASCRIPT MODULES -->
<script src="https://kendo.cdn.telerik.com/2025.3.825/mjs/kendo.all.js" type="module"></script>
<script src="telerik-license.js" type="text/javascript"></script>
<div id="tripsGrid"></div>
<script type="text/javascript" >
$(document).ready(function() {
$("#tripsGrid").kendoGrid({
dataSource: {
transport: {
read: {
url: "http://localhost:54243/api/Dispatch/GetTripsForSelectedDate", // Replace with your actual API endpoint
type: "GET", // <-- key change
dataType: "json",
contentType: "application/json"
},
parameterMap: function (options, type) {
if (type === "read") {
return kendo.stringify({
page: options.page,
pageSize: options.pageSize,
sort: options.sort,
filter: options.filter,
date: $("#datePicker").val() || null // if you have a date picker
});
}
// For create/update/destroy, send the model as JSON.
// If you enable batch: true later, handle options.models[0] instead.
if (type === "create" || type === "update" || type === "destroy") {
return kendo.stringify(options); // 'options' is the dataItem for non-batch
}
}
},
schema: {
model: {
id: "Trip_ID",
fields: {
Trip_ID: { type: "number" },
Route: { type: "string" },
RouteID: { type: "number" },
Start_Dt: { type: "string", editable : true },
LastName: { type: "string", editable : true },
FirstName: { type: "string", editable : true },
StartDesc: { type: "string" },
StartAddr1: { type: "string" },
StartAddr2: { type: "number" },
StartCityID: { type: "number", editable : true },
StartStateID: { type: "number", editable : true },
StartZipID: { type: "number", editable : true },
StartCity : { type: "string", editable : true },
StartState: { type: "string" },
StartZip: { type: "string" }
}
}
},
pageSize: 10, // Optional: for client-side paging
serverPaging: true, // Set to true for server-side paging
serverSorting: true, // Set to true for server-side sorting
serverFiltering: true // Set to true for server-side filtering
},
height: 550,
sortable: true,
pageable: true,
filterable: true,
editable: { mode: "inline", confirmation: "Delete this trip?" },
columns: [
{ command: ["edit", "destroy"], title: " ", width: 180 },
{ field: "Trip_ID", title: "TripID" },
{ field: "Route", title: "Route", format: "{0:c}" },
{ field: "RouteID", title: "RouteID" },
{ field: "Start_Dt", title: "Start Date" },
{ field: "LastName", title: "Last Name" },
{ field: "FirstName", title: "First Name" },
{ field: "StartDesc", title: "Start Desc" },
{ field: "StartAddr1", title: "Addr1" },
{ field: "StartAddr2", title: "Addr2" },
{ field: "StartCityID", title: "Start City ID", editor: startCityDropdownEditor, template: "#: StartCity #" },
{ field: "StartStateID", title: "Start State ID" },
{ field: "StartZipID", title: "Start Zip ID" },
{ field: "StartCity", title: "StartCity", editor: startCityDropdownEditor, template: "#: StartCity #" },
{ field: "StartState", title: "StartState" },
{ field: "StartZip", title: "StartZipcode" }
]
});
});
//&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
function startCityDropdownEditor(container, options) {
$('<input required name="' + options.field + '"/>')
.appendTo(container)
.kendoDropDownList({
optionLabel: "Select city...",
dataTextField: "LkupItem",
dataValueField: "LkupItemID",
valuePrimitive: true, // model field is a number, not an object
filter: "contains", // searchable
autoBind: true,
dataSource: {
transport: {
read: {
url: "http://localhost:54243/api/Dispatch/GetCities", // API below
type: "GET", // keep POST to avoid 405/WebDAV issues
dataType: "json",
contentType: "application/json"
}
},
schema: { data: "data" } , // expect { data: [...] }
requestEnd: function(e) {
// log the raw response payload
console.log("API Response for GetCities:", e.response);
// log the parsed data that DropDownList will bind to
console.log("Parsed City List:", this.data());
}
},
change: function (e) {
// keep StartCity (name) in sync so the display template shows new text
var item = this.dataItem();
if (item && options.model) {
options.model.set("StartCity", item.LkupItem);
}
},
dataBound: function () {
// Ensure selected value shows when editing existing rows
if (options.model.StartCityID != null) {
this.value(options.model.StartCityID);
}
}
});
}
</script>
</asp:Content>
Thanks,
Ravi
Hi,
Would like to dynamically control whether a grid has a slider control for the roles.
The algorithm /flow would look something like this:
grid is declared and options initialized within windows.onload or $(document).ready(function() {});
user makes selection to load grid
data populates the datSource from an API request.
if(dataSource.length > 10 )
then let scrollable = true;
else
scrollable = false;
The idea here is it would dynamically adjust that scrollable option after a certain length threshold would be met.
attached here is how I have my grid set up..also I have the sort and dataBound handlers doing stuff.
Here is inline version of JavaScript / jQuery kendo code that declares and does some initialization:
$("#myGrid").kendoGrid({
width: 1400,
height: 500,
sortable: {
mode: "single",
allowUnsort: false
},
resizable: true,
editable: true,
scrollable: true,
columns: modifiedColumns, // Use updated columns
dataSource: mappingsDS,
selectable: "multiple, row",
Thanks,
George
@( Html.Kendo().Grid((IEnumerable<
Route.StopLocation
>)ViewData["Stops"])
.Name("selectedStops")
.Columns(columns =>
{
columns.Bound(p => p.StopNo).Title("Stop No.");
columns.Bound(p => p.Id).Title("ID");
columns.Bound(p => p.StopLocation).Title("Stop Location");
})
// .Selectable causes NotSupportedException: There is no DataSource Model Id property specified.
.Selectable(s => s.Mode(GridSelectionMode.Multiple))
)
Hello
I have a grid and each row can be expanded, using detailInit, to show an inner grid.
I fetch the data beforehand so that I can populate the grid using local data.
In inner grid I have a column with a delete button - using template I call a delete function passing this as a parameter.
// column definition
{
field: "delete",
title: "Delete",
width: 50,
template: "<span class='delete' onclick='delete(this)'><img src='.delete_icon.png'/></span>"
},
my delete function :
function delete(e) { let Loader = KENDO.KendoLoader($("body")); try { Loader.Show(); let row = $(e).closest("tr"); let grid = $(e).closest(".innerGrid"); let dataItem = KENDO.KendoGrid(grid).GetDataItem(row); let innerRowId= dataItem.id; let parentRow = row.parent().closest(".k-detail-row").prev(); let parentDataItem = KENDO.KendoGrid($("#ParentGrid")).GetDataItem(parentRow); KENDO.KendoGrid(grid).DeleteUI([innerRowId]); // DeleteUI gets array of ids to delete , implemented below // if no rows remain in inner grid, I need to update a column's value in the parent row if (KENDO.KendoGrid(grid).HasRows() == false) { grid.hide(); grid.siblings(".noRecordsFound").show(); let updatedDataObj = { id: parentDataItem.id, someColumnOnParentRow: null } KENDO.KendoGrid($("#ParentGrid")).UpdateUI([updatedDataObj]); // UpdateUI gets array of objects to update, implemented below } } catch (error) { debugger; console.log(error.message); } finally { Loader.Hide(); } }
We have created a own KENDO wrapper script for different widgets. Here is the kendoGrid code:
let KENDO = { KendoComponent(jQueryElement, component, options = null) { let kendoComponent = {}; kendoComponent.InitKendoComponent = function () { let kComponent = jQueryElement.data(component); if (!kComponent) { if (options) { kComponent = jQueryElement[component](options).data(component); } else { kComponent = jQueryElement[component]().data(component); } } return kComponent; }; return kendoComponent; }, KendoGrid(jQueryElement, options = null) { let kendoGrid = {}; let kGrid = KENDO.KendoComponent(jQueryElement, "kendoGrid", options).InitKendoComponent(); if (options) kGrid.setOptions(options); kendoGrid.SetOptions = function (options) { kGrid.setOptions(options); return kendoGrid; } kendoGrid.GetData = function () { return Array.from(kGrid.dataSource.data()); } kendoGrid.GetDataItem = function (jQueryTableRow) { return kGrid.dataItem(jQueryTableRow); } kendoGrid.UpdateUI = function (dataToUpdate = []) { dataToUpdate.forEach(obj => { let dataItem = kGrid.dataSource.get(obj.id); if (dataItem) { for (let prop in obj) { if (prop !== "id") { dataItem.set(prop, obj[prop]); } } } }); return kendoGrid; } kendoGrid.DeleteUI = function (idsToDelete = []) { idsToDelete.forEach(id => { let dataItem = kGrid.dataSource.get(id); if (dataItem) kGrid.dataSource.remove(dataItem); }); return kendoGrid; }; kendoGrid.HasRows = function () { return kGrid.dataSource.data().length > 0; } return kendoGrid; } }
It appears that UpdateUI does not function as it should.
When I test I notice that when the last remaining row of inner grid is deleted, the parent row's column is indeed updated to null, the No Records Found message is shown instead of the inner grid, the parent row gets collapsed, and when I expand it the inner grid is shown with the last remaining row.
Suprisingly, if I comment out the UpdateUI line, the inner grid's row gets deleted, without collapsing the inner grid and the No Records Found message is shown as intended (the parent row's column does not get updated in this case, obviously).
Is it a bug in Kendo ? or am I doing something wrong?
For certain types of data in my grid, I need to define custom filter operators, e.g.:
updateOrAddFilter(fieldKey, {
field: fieldKey, operator: function (item) {
const nItem = normalize(item);
const nValue = normalize(value);
return nItem && nItem.includes(nValue);
}
});
The updateOrAddFilter function then browses through the all the filters currently applied to the grid's dataSource, replaces old current-column filters with the new one and keeps all the other-column ones, and updates the grid's dataSource as such:
grid.dataSource.filter({ logic: "and", filters: updatedFilters });
I've seen your demos on setting up the type: "date" and the format: stuff on the model and on the column display for the grid. Your demo sorts the dates as if they are dates properly. Ours shows the value as null if we set the type to date. It displays the string properly if we set it to type string but still sorts as a string. If we simply set the column to the kendo format and do not use a schema on the datasource, our code still sorts as a string.
https://dojo.telerik.com/TgCibbiL
When I looked at the data in your demo, it looks like the long form GMT. Today, we are instead blocking the script from sending the .NET property types of DateTime and instead sending a pre-formatted string of the date. Ran into some serialization issues when posting those same objects with DateTime properties on them.
Are you returning your DateTime properties as strings but formatted in this GMT when you serialize your .NET data objects back to the JavaScript handlers?
Module Bundlers - Kendo UI Third-Party Tools - Kendo UI for jQuery
The module bundlers page references Vite as an example which leads me to believe that it can be used with Kendo.
However even this basic example doesn't appear to work: https://stackblitz.com/edit/vitejs-vite-i842ucun?file=src%2Fmain.js
Am I doing something wrong?