LIDOR SYSTEMS

Advanced User Interface Controls and Components

Multi Level Grouping in AngularJS Grid

Created: 10 March 2016

By default, Grid directive arranges data in multiple columns and rows, without a tree hierarchy. If we want to show a hierarchical data into the grid, we can do it by creating groups using one or more columns from the grid. In this way we can dynamically re-arrange data in different categories, while still preserving the original data structure.


Grid directive is part of IntegralUI Studio for Web
a suite of UI Components for development of web apps

In order to create a group, we need to drag-drop a column header over the grouping panel above the grid. This will create a group field and grid data will be reorganized. If we drag-drop multiple columns, data will be arranged in multi level groups.

Enable Data Grouping in the Grid

By default, grouping feature is disabled. To enable it, we need to set the grouping property of the Grid directive to point to an object that holds settings for the grouping feature. Currently, there are two available settings:

  • enabled - determines whether data grouping is enabled or not
  • showColumns - determines the visibility of columns by which groups are created

<!DOCTYPE html>

<html>

<head>

<link rel="stylesheet" href="css/integralui.css" />

<link rel="stylesheet" href="css/integralui.grid.css" />

<link rel="stylesheet" href="css/themes/theme-flat-blue.css" />

<script type="text/javascript" src="external/angular.min.js"></script>

<script type="text/javascript" src="js/angular.integralui.min.js"></script>

<script type="text/javascript" src="js/angular.integralui.lists.min.js"></script>

<script type="text/javascript" src="js/angular.integralui.grid.min.js"></script>

</head>

<body>

<div ng-app="appModule" ng-controller="appCtrl">

<iui-grid name="{{gridName}}" columns="columns" rows="rows" grouping="{ enabled: true, showColumns: true }" allow-column-reorder="true"></iui-grid>

</div>

</body>

</html>

In our example, both of these fields are set to true. If you set the showColumns field to false, whenever a column header is drag-dropped over grouping panel, group will be created and column will become hidden. This allows you to remove any unnecessary data from the grid view.

Arrange Grid Data into Multi Level Groups

At first, to create a group we need to press and hold the left mouse button over column header, and then drag the column header over the grouping panel above the grid. During this process, a floating window will appear showing the title of dragged column. By releasing the mouse button over the grouping panel, a group is created and grid data is rearranged accordingly.

By repeating the same process, we can drag-drop multiple columns over grouping panel and create multiple groups. This automatically rearranges the grid data in a hierarchy based on group order. To change the groups order in grouping panel, left-click on the group and drag-drop it over some other group. This enables you to dynamically rearrange the groups and rearrange the grid data.

If you want some column to be excluded from grouping, you can do that by setting the allowGrouping field of column object to false. This prevents the specified column to be dragged over grouping panel. At least one column should have this field set to false.

angular

.module("appModule", ["integralui"])

.controller("appCtrl", ["$scope", "IntegralUIGridService", "$timeout", function($scope, $gridService, $timeout){

$scope.gridName = "gridSample";

$scope.gridLines = 'horizontal';

 

$scope.columns = [

{ id: 2, headerText: "Title", width: 250, allowGrouping: false },

{ id: 1, groupText: "True/False", editorType: 'checkbox', contentAlignment: 'center', width: 30, fixedWidth: true },

{ id: 3, headerText: "Year", headerAlignment: "center", contentAlignment: "center", width: 70 },

{ id: 4, headerText: "Genre", headerAlignment: "center", contentAlignment: "center", width: 150 },

{ id: 5, headerText: "Ratings", headerAlignment: "center", contentAlignment: "center", width: 90 },

{ id: 6, headerText: "Released", headerAlignment: "center", contentAlignment: "center", width: 130 }

];

 

$scope.rows = [

{

id: 1,

text: "Inception",

cells: [{ cid: 1, value: true }, { cid: 2, text: "Inception" }, { cid: 3, text: "2010" }, { cid: 4, text: "Mystery" }, { cid: 5, text: "8.8" }, { cid: 6, text: "16 Jul 2010" } ]

},

{

id: 2,

text: "Gravity",

cells: [{ cid: 1 }, { cid: 2, text: "Gravity" }, { cid: 3, text: "2013" }, { cid: 4, text: "Sci-Fi" }, { cid: 5, text: "7.9" }, { cid: 6, text: "04 Oct 2013" } ]

},

{

id: 3,

text: "Django Unchained",

cells: [{ cid: 1, value: true }, { cid: 2, text: "Django Unchained" }, { cid: 3, text: "2012" }, { cid: 4, text: "Western" }, { cid: 5, text: "8.5" }, { cid: 6, text: "25 Dec 2012" } ]

},

{

id: 4,

text: "Toy Story 3",

cells: [{ cid: 1, value: true }, { cid: 2, text: "Toy Story 3" }, { cid: 3, text: "2010" }, { cid: 4, text: "Animation" }, { cid: 5, text: "8.4" }, { cid: 6, text: "18 Jun 2010" } ]

},

{

id: 5,

text: "The Wolf of Wall Street",

cells: [{ cid: 1, value: true }, { cid: 2, text: "The Wolf of Wall Street" }, { cid: 3, text: "2013" }, { cid: 4, text: "Comedy" }, { cid: 5, text: "8.2" }, { cid: 6, text: "25 Dec 2013" } ]

},

];

}]);

<iui-grid name="{{gridName}}" columns="columns" rows="rows" show-footer="false" grid-lines="gridLines" grouping="{ enabled: true, showColumns: true }" allow-column-reorder="true"></iui-grid>

For some columns that don't have its title set, during drag-drop process we need to show some kind of group title. For this purpose, you can use the groupText field of column object. In our example, the checkbox column doesn't have a title. Therefore, we set the groupText field of this column to "True/False". This allows us to distinct the group created from this column from other groups.

Sorting with Data Grouping

When sorting is enabled, whenever the column header is clicked, the grid data will be sorted by cell values for clicked column. If there are groups present, they are also sorted in the same way. The only exception here is if we click on the column that has a group. For this purpose, it is best to set showColumns field of the grouping property to false.

$scope.sorting = 'none';

var sortColumn = null;

var prevColumn = null;

 

$scope.onColumnClick = function(e){

if (e.column){

if (e.column != prevColumn){

if ($scope.sorting == 'none')

$scope.sorting = 'ascending';

}

else {

if ($scope.sorting == 'ascending')

$scope.sorting = 'descending';

else

$scope.sorting = 'ascending';

}

 

sortColumn = e.column;

prevColumn = e.column;

 

$gridService.sort($scope.gridName, e.column, $scope.sorting);

}

}

<iui-grid name="{{gridName}}" columns="columns" rows="rows" show-footer="false" grid-lines="gridLines" grouping="{ enabled: true, showColumns: true }" allow-column-reorder="true" sorting="sorting" column-click="onColumnClick(e)"></iui-grid>

By clicking on column header, the sort mark will appear on the header right side, stating the sorting order: ascending or descending. To change the sort order, click again on the same column header. If another column is clicked, the sort order will remain.

Related: AngularJS Grid with Custom Sorting

Conclusion

By enabling the grouping feature in Grid directive for AngularJS, you can dynamically rearrange the grid data in different groups. Thus, creating a hierarchy that allows us to see clearly in what category specific data records belong. Changing the order of groups also changes the way data is organized into the grid. Having multiple groups, allows us to create multi level categories.

Arranging the data in multiple groups, does not alter the original data structure. Only the grid layout is changed so that rows are visually separated into groups, which can be expanded or collapsed.

At last, sorting works for groups in the same way for grid data. Whenever a column header is clicked, groups and grid data is sorted in specified order.

Newsletter


Sign-up to our newsletter and you will receive news on upcoming events, latest articles, samples and special offers.
Name: Email: *
*By checking this box, I agree to receive a newsletter from Lidor Systems in accordance with the Privacy Policy. I understand that I can unsubscribe from these communications at any time by clicking on the unsubscribe link in all emails.