Вопрос

This is my first time working with Kendo UI. I have a Kendo UI grid with child nodes. I want to retain the expanded rows after databinding. Right now its getting collapsed after a row is added in the child

I have tried suggestion from here

dataBound: function() {
    this.expandRow(this.tbody.find("tr.k-master-row").first());
}

But this expands the first row only.

How to retain rows? What am I missing?

Codepen

Это было полезно?

Решение

After a lot of playing around with your code example in CodePen, I believe I've come up with an elegant solution that works.

Having worked with Kendo UI for over three years, I've become pretty familiar with some of its inner workings. As such, I'm going to take advantage of one of these - the data-uid attribute. Kendo UI puts these on all <tr> elements in its grid. I chose this attribute because I know that when we call grid.expandRow() we're going to need to fashion a valid jQuery selector to pass in as a parameter. This eliminates the need for us to add our own attributes or classes and the code to handle them.

First, we need to define a variable to hold our row reference. We'll call it expandedRowUid. To set its value, we hook into the detailExpand event of the grid. So, when the user expands a row, we store its data-uid number.

var expandedRowUid;

var grid = $('#grid').kendoGird({
  // ...
  detailExpand: function(e) {
    expandedRowUid = e.masterRow.data('uid');
  }
});

Then, whenever a change is made that causes the master grid to re-bind to its data, we hook into the dataBound event of the grid and re-expand the row that has a data-uid equal to the one stored in expandedRowUid.

var grid = $('#grid').kendoGird({
  // ...
  detailExpand: function(e) {
    expandedRowUid = e.masterRow.data('uid');
  },
  dataBound: function() {
    this.expandRow($('tr[data-uid=' + expandedRowUid + ']'));
  }
});

Here is the working CodePen example.

NOTE: This will only re-expand the last row that was expanded before the data bind is triggered. So, if you expand rows 4, 5, and 2 in that order, and then trigger a data bind, only row 2 will be re-expanded. You can obviously extend this functionality to handle use cases like that though.

Другие советы

GridDetailExpand: function (e) {
   var gridId = e.sender.element[0].id;
   var grid = $("#" + gridId).data("kendoGrid");
   var data = grid.dataItem(e.masterRow);
   addToArray(expandedRows, data.UniqueIdOfYourDataInGrid);
  },
  GridDetailCollapse: function (e) {
   var gridId = e.sender.element[0].id;
   var grid = $("#" + gridId).data("kendoGrid");
   var data = grid.dataItem(e.masterRow);
   removeFromArray(expandedRows, data.UniqueIdOfYourDataInGrid);
  }

And then on databound

var gridId = e.sender.element[0].id;
var grid = $("#" + gridId).data("kendoGrid");
$.each(grid.tbody.find('tr.k-master-row'), function () {
 var data = grid.dataItem(this);
 if (isInArray(expandedRows, data.UniqueIdOfYourDataInGrid)) {
   grid.expandRow(this);
 }
});

Functions required:

var expandedRows = [];

function addToArray(arr, value) {
    for (var i = 0; i < arr.length; i++) {
        if (arr[i] === value) return;
    }

    arr.push(value);
}

function removeFromArray(arr, value) {
    for (var i = 0; i < arr.length; i++) {
        if (arr[i] === value) {
            delete arr[i];
            return;
        }
    }
}

function isInArray(arr, value) {
    for (var i = 0; i < arr.length; i++) {
        if (arr[i] === value) return true;
    }

    return false;
}

Hope this helps ... took me a while to figure it out...

Solution for Retaining Last Expanding row in the parent grid after records added in the child grid get refreshed.

 detailInit: function (e) {
   
    //Get Parent Grid Last expanded Row index
    lastRowIndex = $(e.masterRow).index(".k-master-row");
   
 },
 dataBound: function () {
   
    //Check any parent grid row is expanded based on row index
    if (lastRowIndex != null && lastRowIndex != undefined){
      
      //find the Grid row details based on row index
      var row = $(this.tbody).find("tr.k-master-row:eq(" + lastRowIndex + ")");
      
      //If expand Row exists then it will expanded
      this.expandRow(row);
    }
    else {
      
      //None of the Parent Grid row is expanded then,default First row is expanded
      this.expandRow(this.tbody.find("tr.k-master-row").first());
      
    }
}

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top