1
votes

I'm using SlickGrid with Groupings and need to sort the data within each Group but leave the Grouping (group header row) in the default order.

Sorting seems to sort the column data and then reorder the Grouping Headers per the data.
Has anyone done this or do I have a option/parameter set incorrectly?

Thanks

3
are you grouping by 1 column or multiple columns? In any ways, you can't and shouldn't use the column header to sort when it's grouped, you have to use the grouping function itself to do it with a comparer and so loop again through the grouping function but sorted the way you want. If need be I'll put an example - ghiscoding
I'm not doing anything special. It's a standard grouping with a single column sort using the default comparer. When sorting occurs (on any column), the Group/Header Row is reordered to reflex the data within the child rows. I want the position of the Group/Header row to remain in default position and only the data within the child rows to be sorted. Yes... an example would be helpful, thanks. - user1415445

3 Answers

2
votes

Here is my example of grouping+sorting. Take note that when I want to sort it does a sort against the column you are grouping by, I can't sort with any other columns unless it's the grouping by column (well not the way I coded my function anyway, though you could play with that)

<select id="slc_groupby" name="slc_groupby" onchange="groupByColumn(this.value)">
    <option value="">...</option>
    <option value="assy_number">Assy Number</option>
</select>
<span id="span_group_btn" style="position:absolute; display:none; margin-left:5px; margin-top:20px;">
    <!-- Group sorting, I show this button only after a grouping column is chosen  -->
    <img src="/images/b_updownarrow2.gif" id="img_sorting" border="0" onclick="groupByColumn( $('#slc_groupby').val() )" />
</span>

and here comes the javascript function for grouping+sorting, take note that whenever you click on the sort button (the top one with html ID=img_sorting), it has the effect of regrouping and resorting through the groupByColumn() function (since I'm using the onclick event), though it happens so fast that you don't really see it makes a grouping again... but that's the way I got it working in all browser (Chrome included)

function groupByColumn(column) {
    // sorting direction, if undefined just inverse the current direction of the global sortdir var (sortdir is defined as global variable in slickgrid)
    sortdir = ((sortdir == 1) ? -1 : 1);

    dataView1.groupBy(
        column,
        function (g) {
            return g.value + "  <span style='color:green'>(" + g.count + " items)</span>";
        },
        function (a, b) {
            var a1 = a.value;
            var b1 = b.value;

            // string sorting
            return sortdir * (a1 == b1 ? 0 : (a1 > b1 ? 1 : -1));
        }
    );

    // display the button for group sorting
    $('#span_group_btn').css("display", "inline");
}
2
votes

Since U did not provide source, I can guess that your problem is with the sort method, which sorts only by selected column, so you must first sort by grouping column.

Let's say that you are grouping by UserName and have sortable column Title, your onSort method should look similar to this:

grid.onSort.subscribe(function (e, args) {
  sortdir = args.sortAsc ? 1 : -1;
  sortcol = args.sortCol.field; // Title column

  var comparer = function (a, b) {
    var x = a['UserName'], y = b['UserName'];
    if (x != y)
    {
     return (x < y ? 1 : -1) * sortdir;
    }
    else
    {
     x = a[sortcol];
     y = b[sortcol];
     return (x == y ? 0 : (x > y ? 1 : -1));
    }  
  };

  dataView.sort(comparer, args.sortAsc);
});
0
votes

Lets say you are grouping with 4 different columns - department, faculty, course, semester. While sorting, you manually compare these columns and always sort them in ascending or descending (whichever is your default order in the beginning), for rest of other columns you use sort direction by flipping the result of compare function

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

grid.onSort.subscribe(function(e, args) {
        $(e.target).parents(".slick-header-columns").find(
                ".slick-header-column").removeClass(
                "slick-header-column-sorted");
        var currentCol = $(e.target).hasClass("slick-header-column") ? $(e.target): $(e.target).parents(".slick-header-column");
        currentCol.addClass("slick-header-column-sorted");
        currentCol.find(".slick-sort-indicator").removeClass(args.sortAsc ? "desc" : "asc").addClass(args.sortAsc ? "asc" : "desc");
        var sortdir = args.sortAsc ? 1 : -1;
        var sortcol = args.sortCol.field;
        var items = dataView.getItems();
        items.sort(function(a, b) {
            var deptCompare = a.department == b.department ? 0 : (a.department < b.department ? -1 : 1);
            if (deptCompare === 0) {
                var facultyCompare = a.faculty == b.faculty ? 0 : (a.faculty < b.faculty ? -1 : 1);
                if (facultyCompare === 0) {
                    var courseCompare = a.course == b.course ? 0 : (a.course < b.course ? -1 : 1);
                    if (courseCompare === 0) {
                        var semesterCompare = a.semester == b.semester ? 0 : (a.semester < b.semester ? -1 : 1);
                        if (semesterCompare === 0) {
                            var fieldCompare = comparer(a[sortcol], b[sortcol]);
                            return fieldCompare * sortdir;
                        } else {
                            return semesterCompare;
                        }
                    } else {
                        return courseCompare;
                    }

                } else {
                    return facultyCompare;
                }
            } else {
                return deptCompare;
            }
        });
        dataView.refresh();

    });

Second way to achieve the same is to user comparer in grouping level. You define a comparer for group,

function groupComparer(a, b) {
    var x = a.groupingKey
    var y = b.groupingKey;
    return (x == y ? 0 : (x > y ? 1 : -1));
} 



dataView.setGrouping([
    {
        getter : "department",
        collapsed : false,
        formatter : function(g){
            return g.value;
        },
        comparer : groupComparer
    },{
        getter : "faculty",
        collapsed : false,
        formatter : function(g){
            return g.value;
        },
        comparer : groupComparer
    },{
        getter : "course",
        collapsed : false,
        formatter : function(g){
            return g.value;
        },
        comparer : groupComparer
    },{
        getter : "semester",
        collapsed : false,
        formatter : function(g){
            return g.value;
        },
        comparer : groupComparer
    }
]);

And user regular sorting

grid.onSort.subscribe(function (e, args) {
    dataView.sort(function(a,b){
        var x = a[args.sortCol.field];
        var y = b[args.sortCol.field];

        return (x == y ? 0 : (x > y ? 1 : -1));
    }, args.sortAsc);
});