Chris
Chris

Reputation: 3129

Inserting new row into grid causes a duplicate row

I have a grid where the first row is always going to be an empty row where you can select a lastname from the multicolumn combobox, once you select that person you find then it inserts that record into the grid, then again it re-adds a empty row and you can continue on adding records to the grid.

The huge problem I am having is that when I select a lastname from the combobox, it adds that record, but then it adds a new row (as expected) but that row has the newly added records lastname in the new empty row...

Here is a screen shot of before adding a new record

Before

and here is a screen shot of after I add a new record

After

Does anyone know how to fix this issue and what the cause of it is?

function AddNewRow() {
  let grid = $("#GridList").data("kendoGrid");
  grid.dataSource.insert(0, {
    CustomerID: null,
    FirstName: "",
    LastName: "",
    Address: "",
    City: "",
    Zip: ""
  });
}

var junkData = [{
    "FirstName": "Ben",
    "LastName": "abc",
    ID: 1
  },
  {
    "FirstName": "Bob",
    "LastName": "def",
    ID: 2
  },
  {
    "FirstName": "Joe",
    "LastName": "ghi",
    ID: 3
  },
  {
    "FirstName": "Clarice",
    "LastName": "jkl",
    ID: 4
  },
];

function LNameEditor(container, options) {
  let combobox = $('<input data-text-field="LastName" data-value-field="LastName" data-bind="value:' + options.field + '" />')
    .appendTo(container)
    .kendoMultiColumnComboBox({
      dataTextField: "LastName",
      height: 300,
      columns: [{
        field: "LastName",
        title: "Last Name",
        width: 100
      }],
      filter: "startswith",
      filterFields: ["LastName"],
      dataSource: {
        data: junkData
      },
      change: function(e) {
        let items = e.sender._data()[0];

        let grid = $("#GridList").data("kendoGrid");
        grid.dataSource.insert(1, {
          CustomerID: items.ID,
          FirstName: items.FirstName,
          LastName: items.LastName,
          Address: items.Address,
          City: items.City,
          Zip: items.Zip,
        });

      },
      select: function(e) {}
    });
}


var readonlyEditor = function(container, options) {
  let gridWidget = $("#GridList").data("kendoGrid");
  gridWidget.closeCell();
};

var gridData = [{
    "CustomerID": 3,
    "FirstName": "The Skipper",
    "LastName": "Gilligan",
    "Address": "1 Main St.",
    "City": "Toledo",
    "Zip": "123456"
  },
  {
    "CustomerID": 4,
    "FirstName": "Archie Bunker",
    "LastName": "Edith Bunker",
    "Address": "2 South St.",
    "City": "Memphis",
  }
];

function LoadGrid() {
  $("#GridList").kendoGrid({
    dataSource: {
      data: gridData
    },
    schema: {
      model: {
        fields: {
          CustomerID: {
            type: "number",
            editable: false
          },
          CustomerFirstName: {
            type: "string"
          },
          CustomerLastName: {
            type: "string"
          },
          CustomerAddress1: {
            type: "string"
          },
          City: {
            type: "string"
          },
          Zip: {
            type: "string"
          }
        },
      }
    },
    filterable: {
      mode: "row"
    },
    columns: [{
        title: "<input id='checkAll', type='checkbox', class='check-box' />",
        template: "<input name='Selected' class='checkbox' type='checkbox'>",
        width: "30px"
      },
      {
        field: "CustomerID",
        title: "CustomerID",
        hidden: false,
        headerAttributes: {
          "class": "wrap-header"
        },
        editor: readonlyEditor
      },
      {
        field: "LastName",
        title: "Last Name",
        filterable: {
          cell: {
            showOperators: false,
            operator: "contains"
          }
        },
        editor: LNameEditor,
        template: "#=LastName #"
      },
      {
        field: "FirstName",
        title: "Name",
        filterable: {
          cell: {
            showOperators: false,
            operator: "contains"
          }
        },
        editor: readonlyEditor
      },
      {
        field: "Address",
        title: "Address",
        filterable: {
          cell: {
            showOperators: false,
            operator: "contains"
          }
        },
        editor: readonlyEditor
      },
      {
        field: "City",
        title: "City",
        filterable: {
          cell: {
            showOperators: false,
            operator: "contains"
          }
        },
        editor: readonlyEditor
      },
      {
        field: "Zip",
        title: "Zip",
        filterable: {
          cell: {
            showOperators: false,
            operator: "contains"
          }
        },
        editor: readonlyEditor
      }
    ],
    editable: true,
    scrollable: true,
    sortable: true,
    pageable: false,
    selectable: "row",
    change: function(e) {
      // Function call goes here
      var detailRow = this.dataItem(this.select());
      var optionID = detailRow.get("CustomerID")
    },
    height: 400
  });

  AddNewRow();
}

$(document).ready(function() {

  LoadGrid();

});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://kendo.cdn.telerik.com/2019.1.220/js/kendo.all.min.js"></script>
<link rel="stylesheet" href="https://kendo.cdn.telerik.com/2019.1.220/styles/kendo.common.min.css" />
<link rel="stylesheet" href="https://kendo.cdn.telerik.com/2019.1.220/styles/kendo.rtl.min.css" />
<link rel="stylesheet" href="https://kendo.cdn.telerik.com/2019.1.220/styles/kendo.silver.min.css" />
<link rel="stylesheet" href="https://kendo.cdn.telerik.com/2019.1.220/styles/kendo.mobile.all.min.css" />

<div id="MyDiv">
  <div id="GridList" tabindex="-1"></div>
</div>

Upvotes: 0

Views: 421

Answers (1)

The Dread Pirate Stephen
The Dread Pirate Stephen

Reputation: 3169

There are 2 problems here:

  1. You are not clearing/resetting the "empty" row, but I think you think you are. In the ComboBox's change event, all you are doing is adding a new row at index 1 and that's it...you are leaving row 0 alone, which includes leaving the LastName set to whatever was selected. You need to actually reset row 0. This can be accomplished by removing the current row 0 and replacing it with a "clean" row 0. You can use your AddNewRow() helper to do this.
  2. You are not actually selecting the data from the item chosen from the ComboBox. Within the ComboBox change event, you are just getting the first item from the ComboBox's dataSource, NOT the selected item. You really want the selected item instead of item 0.

If you update the change event to something like this, it should work better:

change: function(e) {
    // THIS IS NOT THE DATA YOU WANT.
    // e.sender is the ComboBox so this will always be "abc"(index 0 of the ComboBox dataSource) rather than the selected item.
    // let items = e.sender._data()[0];
    let items = e.sender._data()[e.sender.selectedIndex];

    let grid = $("#GridList").data("kendoGrid");
    grid.dataSource.insert(1, {
      CustomerID: items.ID,
      FirstName: items.FirstName,
      LastName: items.LastName,
      Address: items.Address,
      City: items.City,
      Zip: items.Zip,
    });

    // Need to "clear" the "empty" row, which is always row 0.
    // We can do this by removing and re-adding the row(among other ways).
    let dataItem = grid.dataSource.at(0);
    grid.dataSource.remove(dataItem);
    AddNewRow();
  }

Working example: https://dojo.telerik.com/@Stephen/EnIruLOm

Upvotes: 1

Related Questions