The moment you find yourself typing the same code over and over again, you know that something is off. You know that the code you are writing is getting WET (Write Everything Twice or We Enjoy Typing).
You need to stop, plan, modularize and DRY it off. You will thank yourself later when the next grid is up in seconds and you are sipping on that cup of of coffee you have been thinking of all afternoon.
Creating editable Kendo UI Grids with dynamic data is like cooking an a-la-carte meal the easy way. As a Technical Support Enginneer at Progress, I have seen plenty of our clients's "kitchens", helped resolve questions and given advice regarding dynamic data and I am here to give you the recipe.
The Dynamic Data Recipe
Ingredients
1. Create a backend with consistent naming of the controller actions. For example:
2. Write a function which creates a Kendo UI Grid with these parameters - gridName, baseUrl, editable and element. The function should make an ajax request and generate the schema model, columns and data source in the success callback. Once the schema, data source and columns are known, initialize the dynamic Kendo UI Grid and append it to the element.
// keep a reference of the date fields for easy formatting
var dateFields = [];
function createGrid(gridName, baseUrl, editable, element) {
$.ajax({
url: baseUrl,
success: function(response) {
var sampleDataItem = response[0];
var model = generateModel(sampleDataItem);
var dataSource = generateDataSource(baseUrl, model, editable);
var columns = generateColumns(sampleDataItem);
var gridOptions = {
dataSource: dataSource,
columns: columns,
pageable: true,
editable: editable,
height: 450
};
if(editable){
columns.push({ command: "destroy", title: " ", width: 170 });
gridOptions.toolbar = ["create", "save", "cancel"];
}
$("<div id='" + gridName + "'></div>").kendoGrid(gridOptions).appendTo(element);
}
});
}
3. Create the helper functions for the data source schema model, columns and data source transport generation
A function to create the dynamic data source schema model
function generateModel(sampleDataItem) {
var model = {};
var fields = {};
for (var property in sampleDataItem) {
if (property.indexOf("ID") !== -1 || property.indexOf("Id") !== -1) {
model["id"] = property;
}
var propType = typeof sampleDataItem[property];
if (propType === "number") {
fields[property] = {
type: "number"
};
if(model.id === property){
fields[property].editable = false;
}
} else if (propType === "boolean") {
fields[property] = {
type: "boolean"
};
} else if (propType === "string") {
var parsedDate = kendo.parseDate(sampleDataItem[property]);
if (parsedDate) {
fields[property] = {
type: "date"
};
dateFields[property] = true;
}
}
}
model.fields = fields;
return model;
}
A function to create the dynamic columns
function generateColumns(sampleDataItem) {
var columnNames = Object.keys(sampleDataItem);
return columnNames.map(function(name) {
return {
field: name,
format: (dateFields[name] ? "{0:D}" : "")
};
});
}
A function to create the dynamic data source
function generateDataSource(baseURL, model, editable) {
var dataSource = {
transport: {
read: {
url: baseURL
}
},
schema: {
model:model
},
pageSize: 10
};
if (editable) {
dataSource.transport.create = {
url: baseURL + "Create"
};
dataSource.transport.update = {
url: baseURL + "Update"
};
dataSource.transport.destroy = {
url: baseURL + "Destroy"
};
}
return dataSource;
}
<div class="editable"></div>
<div class="readonly"></div>
<script>
createGrid("products", "https://demos.telerik.com/kendo-ui/service/products/", true, ".editable");
createGrid("customers", "https://demos.telerik.com/kendo-ui/service/customers/", false, ".readonly");
</script>