a suite of UI Components for development of web apps
Advanced User Interface Controls and Components
Created: 15 July 2015
When we have a large data grid with thousands of rows in multiple columns, we may need to filter this data and show only those rows that matches specific conditions. In many cases, this is done manually from code, by setting different parameters by which data is filtered.
IntegralUI Tree Grid for AngularJS, allows you to create custom templates that can contain custom conditions to filter the grid data. Each column can have a different template with different conditions, and all this is customizable in your application code, as it is demonstrated below.
For first column in the Tree Grid, we are going to create a template, which will display a tree hierarchy for all categories. For this purpose, we will use the standard unordered list html elements, the <ul> <li> tags. The list is populated using the ng-repeat directive. Here is the complete template:
angular
.module("appModule", ["integralui"])
.controller("appCtrl", ["$scope", "IntegralUITreeGridService", "IntegralUIFilterService", "$timeout", function($scope, $gridService, $filterService, $timeout){
$scope.gridName = "gridSample";
$scope.rows = [];
$scope.columns = [
{
id: 2,
headerText: "Category/Name",
width: 400,
allowFilter: true,
filterTemplate: "'categories.html'"
},
{
id: 3,
headerText: "Author/Supplier",
headerAlignment: "center",
contentAlignment: "center",
width: 225,
allowFilter: true,
filterTemplate: "'authors.html'"
},
{
id: 4,
headerText: "Price",
headerAlignment: "center",
contentAlignment: "right",
width: 120,
allowFilter: true,
filterTemplate: "'prices.html'"
}
];
}]);
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="css/integralui.css" />
<link rel="stylesheet" href="css/integralui.checkbox.css" />
<link rel="stylesheet" href="css/integralui.treegrid.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.checkbox.min.js"></script>
<script type="text/javascript" src="js/angular.integralui.treegrid.min.js"></script>
</head>
<body>
<div ng-app="appModule" ng-controller="appCtrl">
<script type="text/ng-template" id="categories.html">
<div class="filter-categories">
<label>Choose categories: </label>
<ul class="filter-list">
<li ng-repeat="item in categories" iui-style="padding-left:{{item.indent}}px">
<input class="item-checkbox" type="checkbox" ng-model="item.checked" /><span class="item-label">{{item.text}}</span>
</li>
</ul>
<div>
<button class="inline-button" ng-click="applyCategories()">Apply</button>
<button class="inline-button" ng-click="cancelCategoriesFilter()">Cancel</button>
</div>
</div>
</script>
<iui-treegrid name="{{gridName}}" columns="columns" rows="rows" allow-filter="true" show-footer="false" allow-cell-focus="false"></iui-treegrid>
</div>
</body>
</html>
/* Filter Template Categories */
.filter-categories
{
cursor: default;
padding: 5px;
}
.filter-list
{
margin: 0;
overflow: auto;
padding: 1px;
margin: 0 0 15px 0;
}
.filter-list li
{
list-style-type: none;
border: thin solid transparent;
padding: 1px 3px;
}
.filter-list li:hover
{
background: white;
border: thin solid gray;
}
.item-checkbox
{
display: inline-block;
vertical-align: middle;
}
.item-label
{
display: inline-block;
vertical-align: middle;
}
.inline-button
{
display: inline-block;
width: 75px;
}
The above code must be set in HTML after application controller is set. So that it is recognized by AngularJS, and data binding is correctly applied.
We are using categories array to store all groups from our grid. This is processed in application controller:
$scope.categories = [];
var resetCategories = function(){
$scope.categories.length = 0;
for (var i = 0; i < $scope.flatData.length; i++){
switch ($scope.flatData[i].id.toString().length){
case 1:
$scope.categories.push({ checked: true, text: $scope.flatData[i].text, indent: 0 });
break;
case 2:
$scope.categories.push({ checked: true, text: $scope.flatData[i].text, indent: 15 });
break;
}
}
}
This template also uses two buttons, the Apply and Cancel button. When Apply button is clicked, the applyCategories function is executed. This sets conditions based on which items are checked, and creates filter parameters. Then the filter method is called, which filters the Grid data:
$scope.applyCategories = function(){
var checkList = [];
for (var i = 0; i < $scope.categories.length; i++){
if ($scope.categories[i].checked)
checkList.push($scope.categories[i].text);
}
var conditions = { value: checkList, operation: '=', join: '|' }
var params = {
callback: function(value){
if (typeof value == 'string' || value instanceof String)
return $filterService.match(value, conditions);
else if (value)
return true;
return false;
}
}
$gridService.filter($scope.gridName, $scope.columns[0], params);
}
$scope.cancelCategoriesFilter = function(){
}
Cancel button when clicked, resets the categories in our template, and also removes the filter from the Tree Grid for specified column.
Lastly, in order this filter template to appear, the specified column must have its allowFilter field set to true and filterTemplate set to the template identifier. This displays the filter icon on right side of column header. When this icon is clicked, a popup window is displayed showing the filter template.
Other columns in our demonstration above uses different templates, created in similar way. The second column uses a filter template that includes string conditions, and the third column includes numeric conditions.
You can create any kind of custom template in your code, using different HTML elements in custom layouts. Only requirement is to add these templates to grid columns, set your own custom conditions and call the filter method.
A complete source code for this sample, including all templates, is available as part of IntegralUI Studio for Web product package.