Search code examples
user-interfacegridkendo-uikendo-grid

Kendo grid cancel button loses new value


I use a grid with a custom editor. I replace common input with a textarea inside colum.

Usecase:

  1. Chack current value of textarea as "test 0"
  2. Press edit button of a grid (of it's row)
  3. Add new value "test 01"
  4. Press Update button of a grid
  5. Check that the new value updated in grid row (works)
  6. Again press edit button of a grid (with new value of "test 01")
  7. Press cancel button of grid (here some magic heppens! and not only with grid but with each custom editing element)
  8. Check that the current value didn't chage from "test 01" to "test 0" (failed).

after cancel the previous value ("test 0" instead of "test 01") is displayed by a grid. The situation is same with values from other columns (not customEditable), e.g. Amount. If I save and then press cancel, the wrong values is displayed but correct values would be saved in db

full grid reload saves situation, but it's not optimal for ajax grid

Grid's datasource:

// bind json result from /Bonuses/GetPagedJsonBonuses
var bonusesDataSource = new kendo.data.DataSource({
    transport: {
        read: "@Url.Action("GetPagedJsonBonuses", "Bonuses")",
        update: {
            url: "@Url.Action("Edit", "Bonuses")",
            type: "PUT"
        },
        create: {
            url: "@Url.Action("Create", "Bonuses")",
            type: "POST"
        },
        parameterMap: function(options, operation) {
            if (operation === "update" || operation === "create") {
                // updates the BonusDTO.EmployeeId with selected value
                if (newValueEmployeeId !== undefined)
                    options.EmployeeId = newValueEmployeeId;
            }
            return options;
        }
    },
    schema: {
        data: "Data", // PagedResponse.Data
        total: "TotalCount", // PagedResponse.TotalCount
        model: {
            id: "BonusId",  // Data
            fields: {
                EmployeeId: { type: "number" },
                EmployeeLastName: {
                    type: "string",
                    editable: true,
                    //validation: { required: {message: "Employee's last name is required"}}
                },
                Amount: {
                    type: "number",
                    editable: true,
                    nullable: false,
                    validation: {
                        required: { message: "Amount is required to be set" }
                    }
                }
            } // fields
        } // model
    }// schema 
});

Grid element looks like this:

// creates bonuses grid control
$("#bonusesGrid").kendoGrid({
    dataSource: bonusesDataSource,
    toolbar: ["create"],
    editable: "inline",
    columns: [
        "BonusId",
        "EmployeeId",
        {
            field: "EmployeeLastName",
            editor: employeeAutocompletingEditor,
            template: "#=EmployeeLastName#"
        },
        "Amount",
        {
            field: "Comment",
            titel: "Comment",
            editor: textareaEditor,
            filterable: {
                operators: {
                    number: {
                        contains: "Contains"
                    }
                }
            }
        },
        {
            command: ["edit"],
            title: " "
        }
    ],
    save: function(e) {
        if (newValueEmployeeId !== undefined && newValueEmployeeLastName !== undefined) {
            e.model.EmployeeId = newValueEmployeeId; // it's a hack to bind model and autocomplete control
            e.model.EmployeeLastName = newValueEmployeeLastName;
        }
    },
    edit: function(e) {
        setCurrentValueEmployeeIdAndLastName(e.model.EmployeeId, e.model.EmployeeLastName);
    },
    cancel: function(e) {
        setCurrentValueEmployeeIdAndLastName(e.model.EmployeeId, e.model.EmployeeLastName);
    }
});

Textarea code is here:

function textareaEditor(container, options) {
    $('<textarea data-bind="value: ' + options.field + '" cols="10" rows="4"></textarea>')
        .appendTo(container);
}

UPDATE 1

After step 4 (change 'test 0' to 'test 01' comment and press Update) I have next request:

  Accept:application/json, text/javascript, */*; q=0.01
  Content-Length:490
  Content-Type:application/x-www-form-urlencoded; charset=UTF-8
  Host:localhost
  Origin:http://localhost
  Referer:http://localhost/
  X-Requested-With:XMLHttpRequest

Body of POST

  Form Dataview sourceview URL encoded
  BonusId:45
  EmployeeId:47
  Employee[EmployeeId]:47
  Employee[UserName]:opetriv
  Employee[LastName]:Oleh Petrivskyy
  Employee[LastNameUkr]:Петрівський Олег Миронович
  EmployeeLastName:Oleh Petrivskyy
  Date:Fri Apr 19 2013 12:00:00
  Amount:2
  **Comment:test 01**
  IsActive:true
  Ulc:ryakh               
  Dlc:Fri Apr 19 2013 12:34:33 GMT+0300 (FLE Daylight Time)

And it's correct as for me.

The response from controller is:

{"BonusId":45,
 "EmployeeId":47,
 "Employee":{"EmployeeId":47,"UserName":"opetriv","LastName":"Oleh      Petrivskyy","LastNameUkr":"Петрівський Олег Миронович"},
 "EmployeeLastName":"Oleh     Petrivskyy","Date":"\/Date(1366362000000)\/","Amount":2,**"Comment":"test    01"**,"IsActive":true,"Ulc":"ryakh               ","Dlc":"\/Date(1366375264603)\/"}

After step 7 (Press cancel and receive this magic) there is no any ajax requests to server. I have an error handler for datasource and it doesn't fire.


Solution

  • It is important what is the response from the server when you press update. Put a handler for the error event of the dataSource and see if it is triggered.

    Check what is the raw response from the server for the update request. It should not contain any errors. Also keep in mind that with the latest version of jQuery empty response is not valid JSON and the error event will be triggered.