Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Simple Slickgrid sorting doesn't work

Is there obvious reason why this Slickgrid example shouldn't work. Basically it doesn't sort on clicking columns.

        var grid;

        var columns = [
        {id:"title", name:"Title", field:"title", sortable: true},
        {id:"duration", name:"Duration", field:"duration", sortable: true},
        {id:"%", name:"% Complete", field:"percentComplete", sortable: true},
        {id:"start", name:"Start", field:"start", sortable: true},
        {id:"finish", name:"Finish", field:"finish", sortable: true},
        {id:"effort-driven", name:"Effort Driven", field:"effortDriven", sortable: true}
        ];

        var options = {
            enableCellNavigation: true,
            enableColumnReorder: false
        };

        $(function() {
            var data = [];
            for (var i = 0; i < 500; i++) {
                data[i] = {
                    id: i,
                    title: "Task " + i,
                    duration: "5 days",
                    percentComplete: Math.round(Math.random() * 100),
                    start: "01/01/2009",
                    finish: "01/05/2009",
                    effortDriven: (i % 5 == 0)
                };
            }

            var dataView = new Slick.Data.DataView();

            grid = new Slick.Grid("#myGrid", dataView, columns, options);
            function comparer(a,b) {
                var x = a[sortcol], y = b[sortcol];
                return (x == y ? 0 : (x > y ? 1 : -1));
            }

            var sortcol = "json_number";
            var sortdir = 1;
            grid.onSort.subscribe(function(e, args) {
                sortdir = args.sortAsc ? 1 : -1;
                sortcol = args.sortCol.field;

                // using native sort with comparer
                // preferred method but can be very slow in IE with huge datasets
                dataView.sort(comparer, args.sortAsc);
            });
            dataView.beginUpdate();
            dataView.setItems(data);
            dataView.endUpdate();
            grid.invalidate();
            grid.render();

            $("#myGrid").show();
        })
like image 790
XoR Avatar asked Apr 26 '11 11:04

XoR


2 Answers

Try adding this listener, which re-renders the grid when rows get shuffled around:

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

Original example here: http://mleibman.github.com/SlickGrid/examples/example4-model.html

like image 192
oscilloscope Avatar answered Oct 31 '22 11:10

oscilloscope


Even though there already is an accepted answer which surely solved the initial question, I wanted to point out a common mistake on stackoverflow while handling Slickgrid's subscribe method.

Let us imagine our grid is in the variable called 'grid', like in most other examples. This occurs in most of the accepted and/or upvoted answers:

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

or

 grid.onSort.subscribe(function(e, args){
      var cols = args.sortCols;

      data.sort(function(dataRow1, dataRow2){
           for (var i = 0, l = cols.length; i < l; i++){
                var field = cols[i].sortCol.field;
                var sign = cols[i].sortAsc ? 1 : -1;
                var value1 = dataRow1[field], value2 = dataRow2[field];
                var result = (value1 == value2 ? 0 : (value1 > value2 ? 1 : -1)) * sign;

                if (result != 0) return result
           }

           return 0;
      })

      grid.invalidate()
      grid.render()
 })

Do this examples work as intended? Yes, they do.. under certain circumstances.

Let us imagine a function which adds a Slickgrid to a list of Slickgrids:

var m_grids = []
function anyName(){
    var grid;
    //..run code
    //..run subscribe
    m_grids.push(grid)
}

So what happends now when we are trying to call any subscribe function, while the subscribe function contains the variable grid? It merely affects the last assigned grid, no matter on which one the subscribe got executed on. The correct way to subscribe those functions is by the args parameter:

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

or

 grid.onSort.subscribe(function(e, args){
      var cols = args.sortCols;

      args.grid.getData().sort(function(dataRow1, dataRow2){
           for (var i = 0, l = cols.length; i < l; i++){
                var field = cols[i].sortCol.field;
                var sign = cols[i].sortAsc ? 1 : -1;
                var value1 = dataRow1[field], value2 = dataRow2[field];
                var result = (value1 == value2 ? 0 : (value1 > value2 ? 1 : -1)) * sign;

                if (result != 0) return result
           }

           return 0;
      })

      args.grid.invalidate()
      args.grid.render()
 })

This might be a minor case since it requires usually more than one Slickgrid on the same page, yet why make it wrong when we could do it correct very easily :)

like image 26
Lain Avatar answered Oct 31 '22 10:10

Lain