Kendo grid loosing selected row

Viewed 651

I'm using Kendo UI for my grid everything works find with that. I can select one or many rows using scroll and shift. The problem is that if I select row 3 and then some event refresh the grid and after that I want to select row 4 too Kendo is selecting all the above rows, in this case from row 1-4.

So my question is how can I solve this issue?

Desired result in the demo: Select Germany, refresh grid, then select until Belgium. The demo is going to select from row 1 to Belgium.

Here is a demo

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8"/>
    <title>Kendo UI Snippet</title>

    <link rel="stylesheet" href="http://kendo.cdn.telerik.com/2016.3.1028/styles/kendo.common.min.css"/>
    <link rel="stylesheet" href="http://kendo.cdn.telerik.com/2016.3.1028/styles/kendo.rtl.min.css"/>
    <link rel="stylesheet" href="http://kendo.cdn.telerik.com/2016.3.1028/styles/kendo.silver.min.css"/>
    <link rel="stylesheet" href="http://kendo.cdn.telerik.com/2016.3.1028/styles/kendo.mobile.all.min.css"/>

    <script src="http://code.jquery.com/jquery-1.12.4.min.js"></script>
    <script src="http://kendo.cdn.telerik.com/2016.3.1028/js/kendo.all.min.js"></script>
  </head>
  <body>
    <button id="refresh">Refresh</button>
    <div id="grid"></div>

    <script>

      $(function () {

        var selectedOrders = [];
        var idField = "OrderID";
                $('#refresh').click(() => {
            $("#grid").getKendoGrid().dataSource.read();
        })
        
        $("#grid").kendoGrid({
          dataSource: {
            type: "odata",
            transport: {
              read: "http://demos.kendoui.com/service/Northwind.svc/Orders"
            },
            schema: {
              model: {
                id: "OrderID",
                fields: {
                  OrderID: { type: "number" },
                  Freight: { type: "number" },
                  ShipName: { type: "string" },
                  OrderDate: { type: "date" },
                  ShipCity: { type: "string" }
                }
              }
            },
            pageSize: 10,
            serverPaging: true,
            serverFiltering: true,
            serverSorting: true
          },
          height: 400,
          selectable: "multiple",
          pageable: {
            buttonCount: 5
          },
          sortable: true,
          filterable: true,
          navigatable: true,
          columns: [
            {
              field: "ShipCountry",
              title: "Ship Country",
              width: 300
            },
            {
              field: "Freight",
              width: 300
            },
            {
              field: "OrderDate",
              title: "Order Date",
              format: "{0:dd/MM/yyyy}"
            }
          ],
          change: function (e, args) {
            var grid = e.sender;
            var items = grid.items();
            items.each(function (idx, row) {
              var idValue = grid.dataItem(row).get(idField);
              if (row.className.indexOf("k-state-selected") >= 0) {
                selectedOrders[idValue] = true;
              } else if (selectedOrders[idValue]) {
                delete selectedOrders[idValue];
              }
            });
          },
          dataBound: function (e) {
            var grid = e.sender;
            var items = grid.items();
            var itemsToSelect = [];
            items.each(function (idx, row) {
              var dataItem = grid.dataItem(row);
              if (selectedOrders[dataItem[idField]]) {
                itemsToSelect.push(row);
              }
            });

            e.sender.select(itemsToSelect);
          }
        });
      });
    </script>
  </body>
</html>

1 Answers

This problem is so similar to the problem I had which I wrote about here, Kendo Grid Persist Row Example. In the example I wrote, I used persistSelection which is recommended.

This behaviour is happening because after the refresh event the grid no longer knows which row was focused previously. So on dataBound, we need to set that focus back. Here's a snippet that might help you.

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8"/>
    <title>Kendo UI Snippet</title>

    <link rel="stylesheet" href="http://kendo.cdn.telerik.com/2016.3.1028/styles/kendo.common.min.css"/>
    <link rel="stylesheet" href="http://kendo.cdn.telerik.com/2016.3.1028/styles/kendo.rtl.min.css"/>
    <link rel="stylesheet" href="http://kendo.cdn.telerik.com/2016.3.1028/styles/kendo.silver.min.css"/>
    <link rel="stylesheet" href="http://kendo.cdn.telerik.com/2016.3.1028/styles/kendo.mobile.all.min.css"/>

    <script src="http://code.jquery.com/jquery-1.12.4.min.js"></script>
    <script src="http://kendo.cdn.telerik.com/2016.3.1028/js/kendo.all.min.js"></script>
  </head>
  <body>
    <button id="refresh">Refresh</button>
    <div id="grid"></div>

    <script>
      $(function() {
        var selectedOrders = [];
        var idField = "OrderID";
        $('#refresh').click(() => {
            $("#grid").getKendoGrid().dataSource.read();
        });
        
        $("#grid").kendoGrid({
          dataSource: {
            type: "odata",
            transport: {
              read: "http://demos.kendoui.com/service/Northwind.svc/Orders"
            },
            schema: {
              model: {
                id: "OrderID",
                fields: {
                  OrderID: { type: "number" },
                  Freight: { type: "number" },
                  ShipName: { type: "string" },
                  OrderDate: { type: "date" },
                  ShipCity: { type: "string" }
                }
              }
            },
            pageSize: 10,
            serverPaging: true,
            serverFiltering: true,
            serverSorting: true
          },
          height: 400,
          selectable: "multiple",
          pageable: {
            buttonCount: 5
          },
          sortable: true,
          filterable: true,
          navigatable: true,
          columns: [
            {
              field: "ShipCountry",
              title: "Ship Country",
              width: 300
            },
            {
              field: "Freight",
              width: 300
            },
            {
              field: "OrderDate",
              title: "Order Date",
              format: "{0:dd/MM/yyyy}"
            }
          ],
          change: function (e, args) {
            var grid = e.sender;
            var items = grid.items();
            items.each(function (idx, row) {
              var idValue = grid.dataItem(row).get(idField);
              if (row.className.indexOf("k-state-selected") >= 0) {
                selectedOrders[idValue] = true;
              } else if (selectedOrders[idValue]) {
                delete selectedOrders[idValue];
              }
            });
          },
          dataBound: function (e) {
            var grid = e.sender;
            var items = grid.items();
            var itemsToSelect = [];
            items.each(function (idx, row) {
              var dataItem = grid.dataItem(row);
              if (selectedOrders[dataItem[idField]]) {
                itemsToSelect.push(row);
              }
            });
            
            if (itemsToSelect.length > 0) {
              var lastRow = itemsToSelect[itemsToSelect.length - 1];
              grid.selectable._lastActive = lastRow;
              grid.current($(lastRow).find("td:first"));
            }

            e.sender.select(itemsToSelect);
          }
        });
      });
    </script>
  </body>
</html>

Related