MammothOne
MammothOne

Reputation: 490

Controlling Group order in a Kendo UI Grid

Is there a way to control the order of the grouping in a Kendo UI grid. There is a group I would like to go before all other groups, but it seems Kendo UI grid sorts the groups alphabetically. I know that adding a space to the grouping name works but that's seems very hackish.

Thanks Leo

Upvotes: 14

Views: 14381

Answers (9)

Harshal
Harshal

Reputation: 133

The below code will push the group that fulfils the if condition to bottom of the grid

group: {
    dir: "asc",
    field: "FieldToGroupBy",
    compare: function (a, b) {
        if (b.value == "GROUP_TO_SHOW_LAST") {
            return -1; // this will push the group to bottom
        }
    }
},

If you want to compare groups with each other, you should use a and b and then set the return value accordingly. You need to play around with the return value based on your requirement.

Note: return value should be any of 0, 1, -1

Upvotes: 1

tony
tony

Reputation: 2392

An old question but I just had the same issue

In theory you can follow the advice here: https://github.com/telerik/kendo-ui-core/issues/4024

$("#grid").kendoGrid({
    ...
    groupable: {
        sort: {
            dir: "asc",
            compare: function compareByTotal(a, b) {
                if (a.items.length === b.items.length) {
                    return 0;
                } else if (a.items.length > b.items.length) {
                    return 1;
                } else {
                    return -1;
                }
            }
        }
    }
}

However this didn't work for me.

What did work for me was...

Add an extra column to your dataSource, so now you have

  • GroupByName
  • GroupByOrder

In your schema do

dataSource = {
                data: dataProperties,
                schema: {
                    model: {
                        fields: {
                            groupByName: {
                                type: "string",
                                from: "dataPropertyDefinition.GroupName"
                            },
                            groupOrderBy: {
                                type: "string",
                                from: "dataPropertyDefinition.groupOrderBy"
                            }
                        }
                    }
                },
                group: {
                    field: "groupOrderBy",
                }
            };

So now you are ordering by groupOrderBy, which can be whatever you like, and you use the groupHeaderTemplate to show the name instead

        const columns: Array<object> = [
            {
                field: "groupOrderBy",
                hidden: true,
                groupHeaderTemplate: function (x: any)
                {
                    return x.items[0].groupByName;
                }
            }

Upvotes: 0

RRR
RRR

Reputation: 116

Here is a simple workaround for this. Not pretty but simple enough...

Just add spaces in front of the text to achieve desirable sorting

   [{ 
      'Value': 1, 
      'Description': 'Description 1', 
      'Grouping': 'Group 1'
    },  
    { 
      'Value': 2, 
      'Description': 'Description 2', 
      'Grouping': ' Group 2'
    },
    { 
      'Value': 3, 
      'Description': 'Description 3', 
      'Grouping': 'Group 3'
    }] 

In the sample code above Group 2 appears before Group 1 because of a leading space.

Upvotes: -1

Yan
Yan

Reputation: 153

Try AddDescending and AddAscending, see examples below

@(Html.Kendo().Chart<T>()
[... other code ...]
.DataSource(ds => ds
    .Read(read => read.Action("action", "controller"))
    .Group(g => g.AddDescending(model=> model.property)) // <-- subtle difference here!
)
[... other code ...]
)

http://www.telerik.com/forums/stacked-chart-legend-order

Upvotes: 5

djs
djs

Reputation: 1690

Kendo's grouping sorts all elements in the array by a given field (for example fooBar), then iterates the sorted elements. In a nutshell, with pseudo code:

if (element[i].fooBar!= element[i-1].fooBar) { 
    StartNewGroup(element[i]);
} else {
    AddToLastGroup(element[i]);
}

Since the sorted array is required to do the grouping, it is tricky to change the sorting. I created code to override the internal groupBy() function, which allows me to sort the grouped results however I like:

function overrideKendoGroupBy() {
    var origFunc = kendo.data.Query.prototype.groupBy;
    kendo.data.Query.prototype.groupBy = function (descriptor) {
        var q = origFunc.call(this, descriptor);

        var data = SortYourData(q.data, descriptor.dir);

        return new kendo.data.Query(data);
    };
}

Call overrideKendoGroupBy() at some point after your page loads. Now just implement a SortYourData() function where q.data is an array of groupings, and descriptor.dir is "asc" or "desc". q.data[n] has an items array that contains the elements from your original data source that are contained in the nth grouping.

Note: This solution only works if you aren't using paging. The pages are broken up before grouping is applied, so all bets are off if your data spans multiple pages.

Upvotes: 3

pat capozzi
pat capozzi

Reputation: 1459

You can add a query after you have defined the datasource and this seems to work

 related.query({
        sort: { field: "Sort", dir: "asc"},
        group: { field: "CategoryName" },
        pageSize: 50
    });

Where related is the name of the datasource

Upvotes: 0

bts
bts

Reputation: 709

There is currently no way to sort a grouping on something other than the group's field. Having a way to sort groups like Telerik does in their non-Kendo grids is my biggest feature request for them right now. So we are stuck using hacks for now.

One hack that works for me is to combine the sorting field and the display field into a new string column that hides the sorting field portion inside a hidden span. This is done on the data source side (for me, in SQL). The new column is then sorted as a string even if the sorting field was a number, so you have to pad appropriately in some cases.

For example, if my data was:

[ 
    { 
      'Name': 'Alice', 
      'Rank': 10, 
      'RankName': '<span class="myHiddenClass">10</span>Alice', 
      ... (other fields)
    },  
    { 
      'Name': 'Bob', 
      'Rank': 9, 
      'RankName': '<span class="myHiddenClass">09</span>Bob', 
      ... (other fields)
    },  
    { 
      'Name': 'Eve', 
      'Rank': 11, 
      'RankName': '<span class="myHiddenClass">11</span>Eve', 
      ... (other fields)
    } 
    ... (Multiple Alice / Bob / Eve records)
]

Then I can group by the RankName field instead of the Name field. It will display the Name field in the group header but be sorted by the Rank field. In this case, Bob will show up as the first group even though Alice was first alphabetically. This works similarly to the space padding you mentioned.

Upvotes: 9

Petur Subev
Petur Subev

Reputation: 20203

Custom sorting direction when grouping is not supported by the Grid - the groups are sorted the same way as the column is sorted (when using client sorting) when there is not grouping. The sorting direction is the same as the default sort in JavaScript.

Upvotes: 0

GodsCrimeScene
GodsCrimeScene

Reputation: 1270

Use columns to specify the order of columns once you have your data such as

columns: [
{
field: "LastName",
title: "Last Name" 
},
{
field: "FirstName",
title: "First Name"
}
]

Upvotes: -2

Related Questions