4

Am working on slick grid where am trying to get the column information like id,name and the new width of column after resize.

I wrote an event which will be triggered when user resizes the column.

grid.onColumnsResized.subscribe(function (e, args) {
           //To Do
        }); 

grid.getColumns() will help but how do i identify which column user has resized. is there a way I can get the column index of the resized column?

some start up code from here will save lot of my time

Thanks

Peru
  • 2,871
  • 5
  • 37
  • 66

2 Answers2

7

The onColumnsResized event triggered by SlickGrid doesn't include any references to the columns which changed.

It's important to note that the width of multiple columns may have changed when this event triggers. Examples of this are:

  • Using the grid option forceFitColumns: true to force the columns to fit in the width of the grid
  • Resizing a column so small it affects the columns to its left

Two possible options for implementing this are:

Check columns after change

SlickGrid stores the previous column widths in the property named previousWidth on each column. You can compare the prevoiusWidth and width values to determine which columns changed.

grid.onColumnsResized.subscribe(function (e, args) {
  //Loop through columns
  for(var i = 0, totI = grid.getColumns().length; i < totI; i++){
    var column = grid.getColumns()[i];
    //Check if column width has changed
    if (column.width != column.previousWidth){
      //Found a changed column - there may be multiple so all columns must be checked
      console.log('Changed column index : ' + i);
      console.log(column);    
    }
  }
}); 

SlickGrid resets the previousWidth values for all columns whenever a column starts being resized.

You can view an example of this approach at http://plnkr.co/edit/W42pBa2ktWKGtqNtQzii?p=preview.

Modifying SlickGrid

If you are hosting SlickGrid and are comfortable maintaining your own version then you could modify it to include column information in the args of the onColumnsResized event.

In slick.grid.js at line 860 amend the code where the event is triggered to include an array containing the indexes of changed columns. You can also include the index of the column which the user resized if this is useful. The below adds properties named changedColumnIndexes and triggeredByColumnIndex which are passed in the args of the triggered event. I've wrapped the changes for this in comments prefixed //MODIFICATION.

.bind("dragend", function (e, dd) {
  var newWidth;

  //MODIFICATION - Add array to capture changed column indexes and variable to capture 
  //               the index of the column which triggered the change
  var changedColumnIndexes = [];
  var triggeredByColumnIndex = getColumnIndex($(this).parent()[0].id.replace(uid, ""));
  //MODIFICATION END

  $(this).parent().removeClass("slick-header-column-active");
  for (j = 0; j < columnElements.length; j++) {
    c = columns[j];
    newWidth = $(columnElements[j]).outerWidth();

    //MODIFICATION - Add column index to array if changed
    if (c.previousWidth !== newWidth) {
      changedColumnIndexes.push(j);
    }
    //MODIFICATION END

    if (c.previousWidth !== newWidth && c.rerenderOnResize) {
      invalidateAllRows();
    }
  }
  updateCanvasWidth(true);
  render();

  //MODIFICATION - Amend trigger for event to include array and triggeredBy column
  trigger(self.onColumnsResized, {changedColumnIndexes: changedColumnIndexes, triggeredByColumnIndex: triggeredByColumnIndex});
  //MODIFICATION END

});

In your own code subscribe to the onColumnsResized event and pickup the changed column index from the args of the event.

grid.onColumnsResized.subscribe(function(e, args) {
  //Triggered by column is passed in args.triggeredByColumnIndex
  console.log('Change triggered by column in index : ' + args.triggeredByColumnIndex);
  console.log(grid.getColumns()[args.triggeredByColumnIndex]);

  //Column array is passed in args.changedColumnIndexes
  console.log('Changed columns are...');
  console.log(args.changedColumnIndexes);

  //Loop through changed columns if necessary
  for (var i = 0, totI = args.changedColumnIndexes.length; i < totI; i++){
    console.log(grid.getColumns()[args.changedColumnIndexes[i]]);
  }
});

You can view an example of this approach at http://plnkr.co/edit/4K6wRtTqSo12SE6WdKFk?p=preview.

Chris C
  • 1,662
  • 1
  • 15
  • 17
  • Is there not a better way i can directly determine the changed column than looping through every column ? – Peru Oct 17 '15 at 07:25
  • @Peru I've updated the answer with more details and examples. The only way to not include a loop in your code would be to modify SlickGrid to fit your needs as detailed in the second option. Also note that I amended / corrected the code in the first option. I previously included a break after a changed column was found, due to multiple columns changing in a single event this wouldn't work. – Chris C Oct 17 '15 at 13:57
  • I've made a small update to the second option so it returns the array of columns whose width changed as well as the column which initially triggered the change (i.e. the one the user resized) – Chris C Oct 17 '15 at 16:35
  • Thanks ! I will go without modifying it :) Slick Grid does keep track of all modified width right. So i can finally get changed width using getcolumns() or should i do anything extra ? – Peru Oct 17 '15 at 18:59
  • @Peru no problem. Nothing extra to do, you can get the final updated column width from the .width property of the column i.e. `grid.getColumns()[0].width`. – Chris C Oct 17 '15 at 20:06
0

Determining column changes by column.width != column.previousWidth wasn't working for me because sometimes the original and new width were different by an insignificant size (e.g. 125.001 and 125).

I used Chris C's logic and made a PR on the 6pac/SlickGrid project. Here's the commit: https://github.com/6pac/SlickGrid/commit/ba525c8c50baf18d90c7db9eaa3f972b040e0a6e

Andrew
  • 2,368
  • 1
  • 23
  • 30