LIDOR SYSTEMS

Advanced User Interface Controls and Components

IntegralUI Web

Native Angular 4 and AngularJS UI Components


TreeView / Filtering


This sample shows how to filter the TreeView content using multiple different conditions in different combinations.

By selecting an option from combo boxes and specifying matching values, you can filter the TreeView so that only those items that matches the specified condition(s) are shown. In this example we can set a filter with 3 conditions using string operations. Furthermore these conditions are combined using the AND / OR operators.

NOTE If child item matches the filter criteria but his parent don't, it will be excluded from the current view. If you want to show it, you can do it by creating a custom filter operation.

By default, filtering is executed using the item's value field to match the specified criteria. If this field value is empty, then the value of item's text field is used.

For filtering operations we are using the IntegralUIFilter service, which provides many ways to set string, numeric or custom filtering using multiple conditions with multiple AND / OR combinations.

NOTE Only built-in filtering operations are presented in this sample. In order to create a custom filtering operation, you would need to create a function in your code and apply it to the callback field of filtering parameter. To see this in action just use the applyCustomFilter function (in sample code), when Apply button is clicked.

Additional information is available in this sample source code.

<!DOCTYPE html>

<html>

<head>

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

<link rel="stylesheet" href="css/integralui.treeview.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.treeview.min.js"></script>

</head>

<body>

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

<iui-treeview name="{{treeName}}" items="items"></iui-treeview>

<div>

<label>Show items where: </label>

<div class="inline-block" style="margin-top:15px">

<select ng-model="selOptions[0]" ng-options="option for option in filterOptions"></select><input ng-model="filterValues[0]" type="text" style="width:125px"/>

</div>

<div class="inline-block" style="width:125px;margin:5px 15px">

<label class="inline-radio"><input type="radio" ng-model="combinations[0]" value="And" />And</label><label class="inline-radio"><input type="radio" ng-model="combinations[0]" value="Or" />Or</label>

</div>

<div class="inline-block">

<select ng-model="selOptions[1]" ng-options="option for option in filterOptions"></select><input ng-model="filterValues[1]" type="text" style="width:125px"/>

</div>

<div class="inline-block" style="width:125px;margin:5px 15px" align="center">

<label class="inline-radio"><input type="radio" ng-model="combinations[1]" value="And" />And</label><label class="inline-radio"><input type="radio" ng-model="combinations[1]" value="Or" />Or</label>

</div>

<div class="inline-block">

<select ng-model="selOptions[2]" ng-options="option for option in filterOptions"></select><input ng-model="filterValues[2]" type="text" style="width:125px"/>

</div>

 

<div class="inline-block" style="margin-top:25px;text-align:center;width:300px;">

<button ng-click="apply()">Apply Filter</button>

<button ng-click="reset()">Reset</button>

</div>

</div>

</div>

</body>

</html>

angular

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

.controller("appCtrl", ["$scope", "IntegralUITreeViewService", "$timeout", function($scope, $treeService, $timeout){

$scope.treeName = "treeSample";

$scope.items = [];

 

$scope.filterOptions = [ '', 'equals', 'does not equal', 'begins with', 'does not begin with', 'ends with', 'does not end with', 'contains', 'does not contain' ];

$scope.filterValues = [ '', '', '' ];

$scope.selOptions = [

$scope.filterOptions[0],

$scope.filterOptions[0],

$scope.filterOptions[0]

];

 

$scope.combinations = [ 'Or', 'Or' ];

 

$scope.data = [

{ id: 1, text: "Dairy", expanded: false },

{ id: 11, pid: 1, text: "Milk" },

{ id: 12, pid: 1, text: "Butter" },

{ id: 13, pid: 1, text: "Cheese" },

{ id: 14, pid: 1, text: "Yogurt" },

{ id: 2, text: "Fruits" },

{ id: 21, pid: 2, text: "Berries", expanded: false },

{ id: 211, pid: 21, text: "BlackBerries" },

{ id: 212, pid: 21, text: "CranBerries" },

{ id: 213, pid: 21, text: "StrawBerries" },

{ id: 22, pid: 2, text: "Pits" },

{ id: 23, pid: 2, text: "Core" },

{ id: 24, pid: 2, text: "Citrus Fruits", expanded: false },

{ id: 241, pid: 24, text: "Oranges" },

{ id: 242, pid: 24, text: "Lemons" },

{ id: 25, pid: 2, text: "Melons" },

{ id: 26, pid: 2, text: "Tropical Fruits" },

{ id: 261, pid: 26, text: "Avocados" },

{ id: 262, pid: 26, text: "Bananas" },

{ id: 263, pid: 26, text: "Dates" },

{ id: 3, text: "Grains" },

{ id: 4, text: "Meat" },

{ id: 41, pid: 4, text: "Beef" },

{ id: 42, pid: 4, text: "Lamb", expanded: false },

{ id: 421, pid: 42, text: "Lamb Breast" },

{ id: 422, pid: 42, text: "Lamb Leg" },

{ id: 423, pid: 42, text: "Lamb Ribs" },

{ id: 43, pid: 4, text: "Pork" },

{ id: 5, text: "Sweets" },

{ id: 6, text: "Vegetables" },

{ id: 7, text: "Water" }

];

 

var initTimer = $timeout(function(){

$treeService.loadData($scope.treeName, $scope.data);

 

$timeout.cancel(initTimer);

}, 1);

 

var getOperation = function(option){

var index = $scope.filterOptions.indexOf(option);

switch (index){

case 1: //equals

return '=';

 

case 2: //does not equal

return '!=';

 

case 3: //begins with

return '->';

 

case 4: //does not begin with

return '->';

 

case 5: //ends with

return '<-';

 

case 6: //does not end with

return '<-';

 

case 7: //contains

return '[]';

 

case 8: //does not contain

return '[]';

}

 

return '';

}

 

var getFormula = function(conditions){

var formula = '';

 

var firstCombination = $scope.combinations[0];

var secondCombination = $scope.combinations[1];

if (conditions.length == 2 && $scope.selOptions[0] == '')

firstCombination = $scope.combinations[1];

 

var firstSymbol = conditions[0].negative ? '!a' : 'a';

var secondSymbol = conditions[1].negative ? '!b' : 'b';

 

if (firstCombination == 'And')

formula = '(' + firstSymbol + ' & ' + secondSymbol + ')';

else

formula = '(' + firstSymbol + ' | ' + secondSymbol + ')';

 

if (conditions.length == 3){

var thirdSymbol = conditions[2].negative ? '!c' : 'c';

 

if (secondCombination == 'And')

formula += ' & ' + thirdSymbol;

else

formula += ' | ' + thirdSymbol;

}

 

return formula;

}

 

$scope.apply = function(){

var filterConditions = [];

for (var i = 0; i < 3; i++){

if ($scope.selOptions[i] != '' && $scope.filterValues[i] != ''){

var currentOperation = getOperation($scope.selOptions[i]);

 

filterConditions.push({

value: $scope.filterValues[i],

operation: currentOperation,

negative: $scope.filterOptions.indexOf($scope.selOptions[i]) % 2 == 0

});

}

}

 

if (filterConditions.length > 0){

var params = {}

 

if (filterConditions.length == 1){

params.conditions = filterConditions[0];

}

else {

params.conditions = filterConditions;

params.formula = getFormula(filterConditions);

}

 

$treeService.filter($scope.treeName, params);

}

else

$scope.reset();

}

 

$scope.reset = function(){

$treeService.filter($scope.treeName);

}

 

// In order to execute this function, just replace the call from click of Apply button to this function

// In this particular case, this function will filter the TreeView so that only items which contain the

// character 's' and does not contain the character 'o', will be shown

$scope.applyCustomFilter = function(){

var match1 = 's';

var match2 = 'o';

 

var params = {

callback: function(value){

if (value.indexOf(match1) >= 0 && value.indexOf(match2) == -1)

return true;

 

return false;

}

}

 

$treeService.filter($scope.treeName, params);

}

}]);

select

{

margin-right: 15px;

width: 150px;

}

.inline-radio

{

margin-right: 15px;

}

button

{

display: inline-block;

margin: 5px;

width: 100px;

height: 22px;

}

.inline-block

{

display: inline-block;

margin: 3px 0;

}