I am using Kendo ui grid for save the data. For Grid i am using Inline edit but my save button is not in individual row, grid data will save on one common button. My issue is below.
I have lots of row in grid like 60 to 100 when I am pressing the save button that grid will loop of all the row which have (means loop will 60 to 100 times).
I want below scenario :
If I edit any 2 to 3 rows or 10 to 20 rows out of 100 and if I press the save button then only that edited row is update not all row. My code for save grid and binding of grid is as below. Please let me know if anyone find any solution.
// Bind Grid
function MakeGridFromXML(data) {
var div = document.getElementById("divValidationPlans");
div.style.display = "block";
if (data.length == 0) {
var customFieldString = "<Fields>" +
"<Field Id=\"TRTitle\" Title=\"TR Title\" Type=\"Text\" Value=\"\" class='k-textbox' />" +
"<Field Id=\"TestType\" Title=\"Test Type\" Type=\"SingleSelect\" Value=\"\" />" +
"<Field Id=\"TestProcedure\" Value=\"\" Title=\"Test Procedure\" Type=\"SingleSelect\" />" +
"<Field Id=\"TestObjectives\" Value=\"\" Title=\"Test Objectives\" Type=\"Text\" /></Fields>";
data.push({ "CustomFields": customFieldString, "TestObjectives": "" });
}
$("#grdTest").html("");
var fieldSchema = [];
var columnSchema = [];
columnSchema.push({
field: "",
width: "30px",
template: "<input id='chkDelete' type='checkbox' />",
});
var counter = 0;
$.each(data, function (index) {
counter = counter + 1;
var isInsertUpdate = false;
var xmldoc = $.parseXML(data[index].CustomFields);
var $xml = $(xmldoc);
var jsonStr = '{';
$xml.find("Fields").find("Field").each(function () {
jsonStr = jsonStr + '"' + $(this).attr("Title").replace(/\s/g, '').replace(/[^\w\s]/gi, '') + '":{';
jsonStr = jsonStr + '"Title":"' + $(this).attr("Title") + '",';
jsonStr = jsonStr + '"Value":"' + $(this).attr("Value") + '",';
jsonStr = jsonStr + '"Id":"' + $(this).attr("Id") + '"},';
if (counter == 1) {
var type = $(this).attr("Type");
switch (type) {
case 'SingleSelect':
if ($(this).attr("Id") != 'TestType' &&
$(this).attr("Id") != 'TestProcedure') {
var fieldXmlString = '';
$.ajax({
url: GetApiUrl('CustomFieldApi/GetCustomField'),
type: 'GET',
data: { id: $(this).attr("Id") },
dataType: 'json',
success: function (resultxml) {
fieldXmlString = resultxml.FieldDefinition;
}
});
columnSchema.push({
field: $(this).attr("Title").replace(/\s/g, '').replace(/[^\w\s]/gi, '') + ".Value",
title: $(this).attr("Title"),
width: "128px",
template: '<label title="#= ' + $(this).attr("Title").replace(/\s/g, '').replace(/[^\w\s]/gi, '') + '.Value#">' + "#=" + $(this).attr("Title").replace(/\s/g, '').replace(/[^\w\s]/gi, '') + ".Value#" + '</label>',
editor: function (container, options) {
isInsertUpdate = true;
var $rowxml = $(fieldXmlString),
isSystemField = $rowxml.attr("IsSystem");
if (isSystemField == '1') {
var bindSource = $rowxml.attr("bindSource"),
bindField = $rowxml.attr("bindField");
$.ajax({
url: GetApiUrl('customfieldapi/GetCfSourceToBind'),
type: 'GET',
data: { BindSource: bindSource, BindField: bindField },
dataType: 'json',
async: false,
success: function (data) {
$('<input data-bind="value:' + options.field + '"/>').appendTo(container).kendoComboBox({
autoBind: false,
dataSource: new kendo.data.DataSource({
data: data,
}),
minLength: 1,
filter: "startswith",
suggest: true
}).data("kendoDropDownList");
}
});
}
else {
$('<input data-bind="value:' + options.field + '"/>').appendTo(container).kendoComboBox({
autoBind: false,
dataSource: new kendo.data.DataSource({
data: fieldXmlString,
schema: {
type: "xml",
data: "/Field/Option",
model: {
fields: {
displayValue: "@Text",
}
}
},
}),
dataTextField: "displayValue",
dataValueField: "displayValue",
minLength: 1,
filter: "startswith",
suggest: true
}).data("kendoDropDownList");
}
}
});
}
else if ($(this).attr("Id") == 'TestType') {
columnSchema.push({
field: $(this).attr("Title").replace(/\s/g, '').replace(/[^\w\s]/gi, '') + ".Value",
title: $(this).attr("Title"),
width: "128px",
editor: function (container, options) {
isInsertUpdate = true;
TestTypeEditor(container, options);
},
template: '<label title="#= ' + $(this).attr("Title").replace(/\s/g, '').replace(/[^\w\s]/gi, '') + '.Value#">' + "#=" + $(this).attr("Title").replace(/\s/g, '').replace(/[^\w\s]/gi, '') + ".Value#" + '</label>',
});
}
else if ($(this).attr("Id") == 'TestProcedure') {
columnSchema.push({
field: $(this).attr("Title").replace(/\s/g, '').replace(/[^\w\s]/gi, '') + ".Value",
title: $(this).attr("Title"),
width: "128px",
editor: TestProcedureEditor,
template: '<label title="#= ' + $(this).attr("Title").replace(/\s/g, '').replace(/[^\w\s]/gi, '') + '.Value#">' + "#=" + $(this).attr("Title").replace(/\s/g, '').replace(/[^\w\s]/gi, '') + ".Value#" + '</label>',
});
}
break;
case "Date":
columnSchema.push({
field: $(this).attr("Title").replace(/\s/g, '').replace(/[^\w\s]/gi, '') + ".Value",
title: $(this).attr("Title"),
width: "128px",
template: '<label title="#= ' + $(this).attr("Title").replace(/\s/g, '').replace(/[^\w\s]/gi, '') + '.Value#">' + "#=" + $(this).attr("Title").replace(/\s/g, '').replace(/[^\w\s]/gi, '') + ".Value#" + '</label>',
editor: function (container, options) {
$('<input data-bind="value:' + options.field + "" + '" maxlength="10">').appendTo(container).kendoDatePicker({
format: "MM/dd/yyyy",
change: function (e) {
var displayDate = e.sender._oldText;
$("#grdTest").data("kendoGrid").dataItem(this.element.closest("tr")).set(options.field, displayDate);
}
});
}
});
break;
case "Number":
columnSchema.push({
field: $(this).attr("Title").replace(/\s/g, '').replace(/[^\w\s]/gi, '') + ".Value",
title: $(this).attr("Title"),
width: "128px",
template: '<label title="#= ' + $(this).attr("Title").replace(/\s/g, '').replace(/[^\w\s]/gi, '') + '.Value#">' + "#=" + $(this).attr("Title").replace(/\s/g, '').replace(/[^\w\s]/gi, '') + ".Value#" + '</label>',
editor: function (container, options) {
$('<input data-bind="value:' + options.field + "" + '">').appendTo(container).kendoNumericTextBox({
min: 0,
change: function (e) {
var displayData = e.sender._old;
$("#grdTest").data("kendoGrid").dataItem(this.element.closest("tr")).set(options.field, displayData);
}
});
}
});
break;
case "Text":
columnSchema.push({
field: $(this).attr("Title").replace(/\s/g, '').replace(/[^\w\s]/gi, '') + ".Value",
title: $(this).attr("Title"),
width: "128px",
template: '<label title="#= ' + $(this).attr("Title").replace(/\s/g, '').replace(/[^\w\s]/gi, '') + '.Value#">' + "#=" + $(this).attr("Title").replace(/\s/g, '').replace(/[^\w\s]/gi, '') + ".Value#" + '</label>',
editor: '<input class="k-textbox" type="text" data-bind="value:' + $(this).attr("Title").replace(/\s/g, '').replace(/[^\w\s]/gi, '') + ".Value" + '" style="display:block; width:80%;" />'
});
break;
//case "CheckBoxList":
// var fieldXmlString = '';
// $.ajax({
// url: GetApiUrl('CustomFieldApi/GetCustomField'),
// type: 'GET',
// data: { id: $(this).attr("Id") },
// dataType: 'json',
// success: function (resultxml) {
// fieldXmlString = resultxml;
// }
// });
// columnSchema.push({
// field: $(this).attr("Title").replace(/\s/g, '').replace(/[^\w\s]/gi, '') + ".Value",
// title: $(this).attr("Title"),
// width: "128px",
// template: "#=" + $(this).attr("Title").replace(/\s/g, '').replace(/[^\w\s]/gi, '') + ".Value#",
// editor: function (container, options) {
// }
// });
// break;
default:
columnSchema.push({
field: $(this).attr("Title").replace(/\s/g, '').replace(/[^\w\s]/gi, '') + ".Value",
title: $(this).attr("Title"),
width: "128px",
template: '<label title="#= ' + $(this).attr("Title").replace(/\s/g, '').replace(/[^\w\s]/gi, '') + '.Value#">' + "#=" + $(this).attr("Title").replace(/\s/g, '').replace(/[^\w\s]/gi, '') + ".Value#" + '</label>',
editor: '<textarea rows="2" data-bind="value:' + $(this).attr("Title").replace(/\s/g, '').replace(/[^\w\s]/gi, '') + ".Value" + '" style="text-overflow:ellipsis; display:block; width:80%; height:100%; font-family:Arial; font-size:12px;color:black"></textarea>'
});
break;
}
}
});
var TestReuqestTitle = data[index].TRTitle == undefined ? "" : data[index].TRTitle.replace(/\r?\n/g, "");
jsonStr = jsonStr + '"CustomFields":{"Id":"CustomFields","Title":"CustomFields","Value":"' + data[index].CustomFields.replace(/\"/g, "\'") + '"},';
jsonStr = jsonStr + '"VPId":{"Id":"VPId","Title":"VPId","Value":"' + data[index].ValidationPlanId + '"},';
jsonStr = jsonStr + '"isInsertUpdate":{"Id":"isInsertUpdateId","Title":"isInsertUpdateId","Value":"' + isInsertUpdate + '"},';
jsonStr = jsonStr + '"TRTitle":{"Id":"TRTitle","Title":"TRTitle","Value":"' + TestReuqestTitle + '"},';
jsonStr = jsonStr + '"TestTypeId":{"Id":"TestTypeId","Title":"TestTypeId","Value":"' + data[index].TestTypeId + '"},';
jsonStr = jsonStr + '"TestObjectives":{"Id":"TestObjectives","Title":"TestObjectives","Value":"' + data[index].TestObjectives + '"},';
jsonStr = jsonStr + '"TestProcedureId":{"Id":"TestProcedureId","Title":"TestProcedureId","Value":"' + data[index].TestProcedureId + '"}';
jsonStr = jsonStr + '}';
fieldSchema.push($.parseJSON(jsonStr));
});
$("#grdTest").kendoGrid({
dataSource: new kendo.data.DataSource({
data: fieldSchema,
schema: {
total: function (result) {
var totalCount = result.length;
return totalCount;
}
},
pageSize: 10
}),
columns: columnSchema,
editable: true,
filterable: true,
pageable: {
input: true,
numeric: false
},
sortable: {
mode: "multiple",
allowUnsort: true
},
resizable: true,
reorderable: true,
toolbar: [
{
name: 'ToolbarButtons',
template: '#= ToolbarButtons()#'
}
],
});
}
//Save Grid Data.
function SaveChanges() {
var grid = $("#grdTest").data("kendoGrid");
for (var i = 0; i < grid.dataSource._data.length; i++) {
$("#grdTest").busyIndicator(true); // show
if (grid.dataSource._data[i].TestTypeId.Value != 'undefined' && grid.dataSource._data[i].TestTypeId.Value != '00000000-0000-0000-0000-000000000000' && grid.dataSource._data[i].TestTypeId.Value != "" &&
grid.dataSource._data[i].TestProcedureId.Value != 'undefined' && grid.dataSource._data[i].TestProcedureId.Value != '00000000-0000-0000-0000-000000000000' && grid.dataSource._data[i].TestProcedureId.Value != "") {
var strFieldXml = grid.dataSource._data[i].CustomFields.Value;
var fieldXmldoc = $.parseXML(strFieldXml);
var $fieldXml = $(fieldXmldoc);
grid.dataSource._data[i].forEach(function (field) {
if (field.Title != 'CustomFields' && field.Title != 'VPId' && field.Title != 'TestTypeId' && field.Title != 'TestProcedureId') {
$fieldXml.find("Fields").find("Field").each(function () {
if ($(this).attr("Id") == field.Id) {
$(this).attr("Value", field.Value.toString().replace(/["'<>\r\n]/g, ""));
}
});
}
});
grid.dataSource._data[i].CustomFields.Value = (new XMLSerializer()).serializeToString($fieldXml[0]);
var vp = {
VMId: $('#hdnVMId').val(),
ValidationPlanId: grid.dataSource._data[i].VPId.Value,
TRTitle: grid.dataSource._data[i].TRTitle.Value,
TestTypeId: grid.dataSource._data[i].TestTypeId.Value,
TestProcedureId: grid.dataSource._data[i].TestProcedureId.Value,
TestObjectives: grid.dataSource._data[i].TestObjectives.Value.replace(/["'<>\r\n]/g, ""),
CustomFields: grid.dataSource._data[i].CustomFields.Value,
};
if (grid.dataSource._data[i].VPId.Value != 'undefined' && grid.dataSource._data[i].VPId.Value != '00000000-0000-0000-0000-000000000000' && grid.dataSource._data[i].VPId.Value != "") {
$.ajax({
url: GetApiUrl('ValidationPlanApi/Put'),
type: 'PUT',
data: JSON.stringify(vp),
contentType: "application/json;charset=utf-8",
success: LoadValidationPlans,
async: false,
});
}
else {
$.ajax({
url: GetApiUrl('ValidationPlanApi/Post'),
type: 'POST',
data: JSON.stringify(vp),
contentType: "application/json;charset=utf-8",
success: LoadValidationPlans,
async: false,
});
}
}
}
$("#grdTest").busyIndicator(false); // hide
return true;
}