12

I'm working with SlickGrid, binding data directly to the grid from an Ajax call. It's working well at the moment, the grid updates dynamically and is sortable, and I'm using a custom formatter for one column:

var grid;
var columns = [{
  id: "time",
  name: "Date",
  field: "time"
},
{
  id: "rating",
  name: "Rating",
  formatter: starFormatter // custom formatter 
}
];
var options = {
  enableColumnReorder: false,
  multiColumnSort: true
};
// When user clicks button, fetch data via Ajax, and bind it to the grid. 
$('#mybutton').click(function() {
  $.getJSON(my_url, function(data) {
    grid = new Slick.Grid("#myGrid", data, columns, options);
  });
});

However, I want to apply a class to rows in the grid based on the value of the data, so it appears I need to use a DataView instead. The DataView example on the SlickGrid wiki is rather complicated, and has all kinds of extra methods.

Please could someone explain how I simply convert data to a DataView - both initially and on Ajax reload - while leaving the grid sortable, and continuing to use my custom formatter? (I don't need to know how to apply the class, literally just how to use a DataView.)

I'm hoping it's one or two extra lines inside the .getJSON call, but I fear it may be more complicated than that.

Community
  • 1
  • 1
flossfan
  • 10,554
  • 16
  • 42
  • 53

3 Answers3

20

The key pieces are to initialise the grid with a dataview as data source, wire up events so that the grid responds to changes in the dataview and finally feed the data to the dataview. It should look something like this:

dataView = new Slick.Data.DataView();
grid = new Slick.Grid("#myGrid", dataView, columns, options);

// wire up model events to drive the grid
dataView.onRowCountChanged.subscribe(function (e, args) {
  grid.updateRowCount();
  grid.render();
});

dataView.onRowsChanged.subscribe(function (e, args) {
  grid.invalidateRows(args.rows);
  grid.render();
});

// When user clicks button, fetch data via Ajax, and bind it to the dataview. 
$('#mybutton').click(function() {
  $.getJSON(my_url, function(data) {
    dataView.beginUpdate();
    dataView.setItems(data);
    dataView.endUpdate();
  });
});

Note that you don't need to create a new grid every time, just bind the data to the dataview.

If you want to implement sorting you'll also need to tell the dataview to sort when the grid receives a sort event:

grid.onSort.subscribe(function (e, args) {
  sortcol = args.sortCol.field;  // Maybe args.sortcol.field ???
  dataView.sort(comparer, args.sortAsc);
});

function comparer(a, b) {
  var x = a[sortcol], y = b[sortcol];
  return (x == y ? 0 : (x > y ? 1 : -1));
}

(This basic sorting is taken from the SlickGrid examples but you may want to implement something home-grown; without using the global variable for example)

njr101
  • 9,499
  • 7
  • 39
  • 56
  • Thanks! This actually works well, with one exception: on sorting the grid, I get a javascript error: `Uncaught TypeError: Cannot read property 'field' of undefined`. Any idea where `args.sortCol.field` should get defined? – flossfan Jul 23 '12 at 11:58
  • NB: I'd like all columns to be sortable. – flossfan Jul 23 '12 at 11:58
  • Sounds like a typo in the `args.sortCol.field` property reference. The args parameter is passed in to the `onSort` callback. Just put a `console.log(args);` at the top of the callback and check the correct property name for the sortfield (see latest edit). Make sure you check capitilsation carefully. These parameters have been changed in some recent SlickGrid versions so it may not be exactly correct. But the basics are right and this will indeed sort on any column. – njr101 Jul 23 '12 at 14:06
  • 1
    You were right, it was a typo. This answer couldn't have been any better - THANK YOU. – flossfan Jul 23 '12 at 14:33
2

The following does a good job explaining dataView: https://github.com/mleibman/SlickGrid/wiki/DataView

akif1
  • 649
  • 6
  • 6
0

multiColumnSort: true ==> sortCol type : Arrays.
multiColumnSort: false ==> sortCol type : Object.