添加链接
link管理
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接
Currently working on a grid project and cannot solve this particular bug.
Steps to recreate:
1. Create a new row by clicking on the create button

2. Delete a row by clicking on the delete button

3. Click on Create to create a new row and the JS console spits out: 'kendo.all.min.js:30 Uncaught TypeError: Cannot read property 'uid' of undefined'
- The create is blocked and the only way to create a new row after this is to refresh the browser.

The offending code block in the kendo source is:

cancelRow: function (){<br><span style= "line-height: 1.5;" > var e,t = this ,<br>n=t._editContainer;<br>n&&(e = t._modelForContainer(n),<br>t._destroyEditable(),<br>t.dataSource.cancelChanges(e),<br>t._displayRow( "popup" !==t._editMode()?n:t.tbody.find( "[" +pt.attr( "uid" )+ "=" +e.uid+ "]" )))},</span>

My JS for this:

<p>$(document).ready( function () {<br><br> var MyKendoVar = MyKendoVar || {};<br><br> var projectDataSource = new kendo.data.DataSource(<br>              {<br>                   transport: {<br>                        read:<br> function (options) {<br>                                apiService.projectsGet( function (result) {<br>                                  options.success(result);<br>                                });<br>                         },<br><br>                      create: function (options) {<br>                            closeDialogue();<br>                            insertLoading();<br>                            apiService.projectsCreate(options.data, function (result) {<br>                             console.log(result.ProjectId + ", " + result.ProjectDescriptiveId);<br>                             options.success(result);<br>                            });<br><br>                     },<br><br>                      destroy: function (options) {<br>                           apiService.projectsDelete(options.data.ProjectId, function (result) {<br>                               options.success(result)<br> //window.location.reload(true);<br>                         });<br>                     },<br><br>                      update: function (options) {<br>                            closeDialogue();<br>                            insertLoading();<br>                            apiService.projectsUpdate(options.data.ProjectId, options.data, function (result) {<br>                             options.success(result);<br>                            });<br>                     },<br>                  },<br><br>                  sync: function (e) {<br>                        console.log("sync complete");<br>                   },<br><br>                  // schema configuration....<br>                 schema: {<br>                       errors: function (response) {<br>                           return response.myError;<br>                        },<br>                      model: {<br>                            id: "ProjectId",<br>                            fields: {<br>                               ProjectId: { type: "number", editable: false, nullable: true },<br>                             ProjectDescriptiveId: { type: "string", validation: { required: true, min: 4 } },<br>                               ProjectName: { type: "string", validation: { required: true, min: 4 } },<br>                                StartDate: { type: "date", validation: { required: true } },<br>                                StreetAddress: { type: "string", validation: { required: true, min: 4 } },<br>                              Suburb: { type: "string", validation: { required: true, min: 3 } },<br>                             State: { type: "string", validation: { required: true, min: 3 } },<br>                              Postcode: { type: "string", validation: { required: true, min: 4 } },<br>                           }<br>                       }<br>                   },<br><br>                  pageSize: 10,<br>                   sort: { field: "ProjectId", dir: "desc" }<br><br>               });<br><br> $("#grid").kendoGrid({<br>      dataSource: projectDataSource,<br>      toolbar: [{ name: "create", text: "Create new project" }],<br>      pageable: {<br>         refresh: true<br>       },<br>      height: 650,<br>        editable: {<br>         mode: "popup",<br>          template: kendo.template($("#updateTemplate").html())<br>       },<br>      columns: [<br>          { field: 'ProjectName', title: 'Project Name' },<br>            {<br>               title: "Address",<br>               template: "#= StreetAddress + ', ' + Suburb + ' ' + Postcode + ' ' + State #"<br>           },<br>          {<br>               field: 'StartDate',<br>             title: 'Start Date',<br>                type: 'date',<br>               format: '{0:dd-MM-yyyy}',<br>               width: '110px'<br>          },<br>          { field: 'ProjectDescriptiveId', title: 'Project Code', width: '200px' },<br>               {<br>                   command: [{ name: "edit" }, {<br>                       name: "Delete", text: "", click: function (e) { initalizeDeleteWindow(this.dataItem($(e.target).closest("tr"))); }<br>                  }], title: "&nbsp;", width: "140px"<br>             }],<br><br>     /////////<br>       edit: function () {<br>         var $win = $('.k-window');<br><br>          // set title<br>            if (MyKendoVar.editorType === 'add') {<br>              $win.find('.k-window-title').html("Create new project");<br>                $win.find('.k-grid-update').html("Create");<br>         }<br>           else {<br>              $win.find('.k-window-title').html("Update project details");<br>                $win.find('.k-grid-update').html("Update");<br><br>         }<br>       },<br><br>      dataBound: function () {<br>            // add event listener to EDIT button<br>            $('#grid > tbody > tr > td > a.k-button.k-button-icontext.k-grid-edit').on('click', function (evt) {<br>                MyKendoVar.editorType = "edit";<br>         });<br>         $('body > section.section - container.top - margin > div > div.k - header.k - grid - toolbar > a').on('click', function (evt) {<br>             MyKendoVar.editorType = "add";<br>          })<br>      }<br>   })<br><br>  $('#logout').on('click', function () {<br>      $('#logoutForm').submit()<br>   })<br><br>  $('#modalCancel').on('click', closeModalAndOverlay);<br><br><br>    function customModalShow() {<br>        $('#modalOverlay, #customModal').show(200);<br> }<br><br>   function overlayHide() {<br>        $('#modalOverlay').hide(200);<br>   }<br><br>   function closeModalAndOverlay() {<br>       $('#customModal, #modalOverlay').hide(200);<br> }<br><br>   function closeModal() {<br>     $('#customModal').hide(200);<br>    }<br><br>   function closeDialogue() {<br>      $('.k-window').hide(200);<br>   }<br><br>   function initalizeDeleteWindow(dataItem) {<br>      $('#modalTitlebarSpan').text("Delete project");<br>     $('#contentParagraph').text("Do you really want to delete " + dataItem.ProjectName + "?");<br>      $('#modalConfirm').text("Delete");<br>      $('#modalConfirm').off();<br>       $('#modalConfirm').on('click', function () { executeDelete(dataItem); });<br>       customModalShow(); // show delete modal<br> }<br><br>   function executeDelete(dataItem) {<br>      console.log("doing remove()")<br>       projectDataSource.remove(dataItem);<br>     console.log("finishing remove and starting sync");<br>      projectDataSource.sync();<br>       console.log("finished sync");<br>       closeModal();<br>       insertLoading();<br>    }<br><br>   function insertLoading() {<br>      $(".k-grid").prepend("<div class='k-loading-mask' style='width:100%;height:100%'><span class='k-loading-text'>Loading...</span><div class='k-loading-image'><div class='k-loading-color'></div></div></div>");<br>  }<br>});</p><p>var apiService = {<br><br>   settings: {<br>     /// <field type="String" /><br>       projectsEndpoint: settings.apiEndpoint + "projects"<br> },<br><br>  projectsGet: function (successCallback) {<br>       this.callApi(this.settings.projectsEndpoint, 'GET', null, null, successCallback);<br>   },<br><br>  projectsCreate: function (data, successCallback) {<br>      this.callApi(this.settings.projectsEndpoint, 'POST', "application/json; charset=utf-8", data, successCallback);<br>     $(".k-grid-update").addClass("k-state-disabled").removeClass("k-grid-update");<br>  },<br><br>  projectsDelete: function (projectId, successCallback) {<br>     this.callApi(this.settings.projectsEndpoint + '/' + projectId, 'DELETE', "application/json; charset=utf-8", null, successCallback);<br> },<br><br>  projectsUpdate: function (projectId, data, successCallback) {<br>       this.callApi(this.settings.projectsEndpoint + '/' + projectId, 'PUT', "application/json; charset=utf-8", data, successCallback);<br>        $(".k-grid-update").addClass("k-state-disabled").removeClass("k-grid-update");<br>  },<br><br>  callApi: function (path, method, contentType, data, successCallback, failureCallback) {<br>     /// <param name="path" type="String" /><br>       /// <param name="method" type="String" /><br>     /// <param name="contentType" type="String" /><br>        /// <param name="successCallback" type="Function" /><br>      /// <param name="failureCallback" type="Function" /><br>      $.ajax({<br>            url: path,<br>          type: method,<br>           contentType: contentType,<br>           data: JSON.stringify(data),<br>         crossDomain: true,<br>          beforeSend: function (request) {<br>                request.setRequestHeader('Authorization', 'Bearer ' + settings.idToken);<br>            },<br>          success: function (result) {<br>                successCallback(result);<br>                $('#modalOverlay').hide(200);<br>               $('.k-overlay').hide(200);<br>              $(".k-loading-mask").remove();<br>              $(".k-state-disabled").removeClass("k-state-disabled").addClass("k-grid-update");<br>           },<br>          error: function (request, status, error) {<br>              if (request.status == 400) {<br>                    alert("There was a problem with your request: " + request.responseText);<br>                }<br>               else if (request.status == 401) {<br>                   alert("Looks like your login expired - Press Ok to go back to the login screen.");<br>                  window.location = '/';<br>              }<br>               else {<br>                  alert("Error: " + request.responseText)<br>             }<br>               $('#modalOverlay').hide(200);<br>               $(".k-state-disabled").removeClass("k-state-disabled").addClass("k-grid-update");<br>               $(".k-loading-mask").remove();<br>              $('.k-overlay').hide(200);<br>          }<br>       });<br> }<br>};</p>
$(document).ready(function () {
var MyKendoVar = MyKendoVar || {};
var projectDataSource = new kendo.data.DataSource(
transport: {
read:
function (options) {
apiService.projectsGet(function (result) {
options.success(result);
create: function (options) {
closeDialogue();
insertLoading();
apiService.projectsCreate(options.data, function (result) {
console.log(result.ProjectId + ", " + result.ProjectDescriptiveId);
options.success(result);
destroy: function (options) {
apiService.projectsDelete(options.data.ProjectId, function (result) {
options.success(result)
//window.location.reload(true);
update: function (options) {
closeDialogue();
insertLoading();
apiService.projectsUpdate(options.data.ProjectId, options.data, function (result) {
options.success(result);
sync: function (e) {
console.log("sync complete");
// schema configuration....
schema: {
errors: function (response) {
return response.myError;
model: {
id: "ProjectId",
fields: {
ProjectId: { type: "number", editable: false, nullable: true },
ProjectDescriptiveId: { type: "string", validation: { required: true, min: 4 } },
ProjectName: { type: "string", validation: { required: true, min: 4 } },
StartDate: { type: "date", validation: { required: true } },
StreetAddress: { type: "string", validation: { required: true, min: 4 } },
Suburb: { type: "string", validation: { required: true, min: 3 } },
State: { type: "string", validation: { required: true, min: 3 } },
Postcode: { type: "string", validation: { required: true, min: 4 } },
pageSize: 10,
sort: { field: "ProjectId", dir: "desc" }
$("#grid").kendoGrid({
dataSource: projectDataSource,
toolbar: [{ name: "create", text: "Create new project" }],
pageable: {
refresh: true
height: 650,
editable: {
mode: "popup",
template: kendo.template($("#updateTemplate").html())
columns: [
{ field: 'ProjectName', title: 'Project Name' },
title: "Address",
template: "#= StreetAddress + ', ' + Suburb + ' ' + Postcode + ' ' + State #"
field: 'StartDate',
title: 'Start Date',
type: 'date',
format: '{0:dd-MM-yyyy}',
width: '110px'
{ field: 'ProjectDescriptiveId', title: 'Project Code', width: '200px' },
command: [{ name: "edit" }, {
name: "Delete", text: "", click: function (e) { initalizeDeleteWindow(this.dataItem($(e.target).closest("tr"))); }
}], title: "&nbsp;", width: "140px"
/////////
edit: function () {
var $win = $('.k-window');
// set title
if (MyKendoVar.editorType === 'add') {
$win.find('.k-window-title').html("Create new project");
$win.find('.k-grid-update').html("Create");
else {
$win.find('.k-window-title').html("Update project details");
$win.find('.k-grid-update').html("Update");
dataBound: function () {
// add event listener to EDIT button
$('#grid > tbody > tr > td > a.k-button.k-button-icontext.k-grid-edit').on('click', function (evt) {
MyKendoVar.editorType = "edit";
$('body > section.section - container.top - margin > div > div.k - header.k - grid - toolbar > a').on('click', function (evt) {
MyKendoVar.editorType = "add";
$('#logout').on('click', function () {
$('#logoutForm').submit()
$('#modalCancel').on('click', closeModalAndOverlay);
function customModalShow() {
$('#modalOverlay, #customModal').show(200);
function overlayHide() {
$('#modalOverlay').hide(200);
function closeModalAndOverlay() {
$('#customModal, #modalOverlay').hide(200);
function closeModal() {
$('#customModal').hide(200);
function closeDialogue() {
$('.k-window').hide(200);
function initalizeDeleteWindow(dataItem) {
$('#modalTitlebarSpan').text("Delete project");
$('#contentParagraph').text("Do you really want to delete " + dataItem.ProjectName + "?");
$('#modalConfirm').text("Delete");
$('#modalConfirm').off();
$('#modalConfirm').on('click', function () { executeDelete(dataItem); });
customModalShow(); // show delete modal
function executeDelete(dataItem) {
console.log("doing remove()")
projectDataSource.remove(dataItem);
console.log("finishing remove and starting sync");
projectDataSource.sync();
console.log("finished sync");
closeModal();
insertLoading();
function insertLoading() {
$(".k-grid").prepend("<div class='k-loading-mask' style='width:100%;height:100%'><span class='k-loading-text'>Loading...</span><div class='k-loading-image'><div class='k-loading-color'></div></div></div>");

var apiService = {
settings: {
/// <field type="String" />
projectsEndpoint: settings.apiEndpoint + "projects"
projectsGet: function (successCallback) {
this.callApi(this.settings.projectsEndpoint, 'GET', null, null, successCallback);
projectsCreate: function (data, successCallback) {
this.callApi(this.settings.projectsEndpoint, 'POST', "application/json; charset=utf-8", data, successCallback);
$(".k-grid-update").addClass("k-state-disabled").removeClass("k-grid-update");
projectsDelete: function (projectId, successCallback) {
this.callApi(this.settings.projectsEndpoint + '/' + projectId, 'DELETE', "application/json; charset=utf-8", null, successCallback);
projectsUpdate: function (projectId, data, successCallback) {
this.callApi(this.settings.projectsEndpoint + '/' + projectId, 'PUT', "application/json; charset=utf-8", data, successCallback);
$(".k-grid-update").addClass("k-state-disabled").removeClass("k-grid-update");
callApi: function (path, method, contentType, data, successCallback, failureCallback) {
/// <param name="path" type="String" />
/// <param name="method" type="String" />
/// <param name="contentType" type="String" />
/// <param name="successCallback" type="Function" />
/// <param name="failureCallback" type="Function" />
$.ajax({
url: path,
type: method,
contentType: contentType,
data: JSON.stringify(data),
crossDomain: true,
beforeSend: function (request) {
request.setRequestHeader('Authorization', 'Bearer ' + settings.idToken);
success: function (result) {
successCallback(result);
$('#modalOverlay').hide(200);
$('.k-overlay').hide(200);
$(".k-loading-mask").remove();
$(".k-state-disabled").removeClass("k-state-disabled").addClass("k-grid-update");
error: function (request, status, error) {
if (request.status == 400) {
alert("There was a problem with your request: " + request.responseText);
else if (request.status == 401) {
alert("Looks like your login expired - Press Ok to go back to the login screen.");
window.location = '/';
else {
alert("Error: " + request.responseText)
$('#modalOverlay').hide(200);
$(".k-state-disabled").removeClass("k-state-disabled").addClass("k-grid-update");
$(".k-loading-mask").remove();
$('.k-overlay').hide(200);

Any ideas would be appreciated.

Hello Paul,
I managed to format most parts of the code but the provided information is not sufficient enough in order to determine what exactly goes wrong.
Does the problem still persist if you remove the custom logic that is executed when the delete button is pressed?
name: "Delete" ,
text: "" ,
click: function (e) {
initalizeDeleteWindow( this .dataItem($(e.target).closest( "tr" )));
Does the same problem reproduce if you use a standard Kendo UI delete command?
Looking forward to your reply.
Regards,
Alexander Valchev
Telerik by Progress Get started with Kendo UI in days. Online training courses help you quickly implement components into your apps. Thanks for the response.
Yes, the problem still occurs when you remove the custom delete logic.
The problem ended up being a mistake in the selector in the dataBound function.
You can close this case.