Skip to content
99 changes: 99 additions & 0 deletions misc/tutorial/218_multi_select_filter.ngdoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
@ngdoc overview
@name Tutorial: 218 Multiselect Filters
@description

Steps to use:
<ol><li>Add 'ui.grid.multiselect.filter' module dependency
<li>Add a filterHeaderTemplate using the multi-select-filter directive
</ol>
@example
<example module="app">
<file name="app.js">
var app = angular.module('app', ['ngAnimate', 'ngTouch', 'ui.grid', 'ui.grid.selection','ui.grid.multiselect.filter']);

app.controller('MainCtrl', ['$scope', '$http', 'uiGridConstants', function ($scope, $http, uiGridConstants) {
var today = new Date();
var nextWeek = new Date();
nextWeek.setDate(nextWeek.getDate() + 7);
$scope.filtered = function(terms){
console.log(terms);
}
$scope.gridOptions = {
enableFiltering: true,
onRegisterApi: function(gridApi){
$scope.gridApi = gridApi;
},
columnDefs: [
{ field: 'name', filterHeaderTemplate: '<div multi-select-filter on-filter="grid.appScope.filtered($terms)"></div>' },
{ field: 'gender',
filterHeaderTemplate: '<div class="ui-grid-filter-container" ng-repeat="colFilter in col.filters"><div my-custom-dropdown></div></div>',
filter: {
term: 1,
options: [ {id: 1, value: 'male'}, {id: 2, value: 'female'}] // custom attribute that goes with custom directive above
},
cellFilter: 'mapGender' },
{ field: 'company', filterHeaderTemplate: '<div multi-select-filter on-filter="grid.appScope.filtered($terms)"></div>' },
{ field: 'email', enableFiltering: false },
{ field: 'phone', enableFiltering: false },
{ field: 'age', filterHeaderTemplate: '<div multi-select-filter on-filter="grid.appScope.filtered($terms)"></div>'
},
{ field: 'mixedDate', cellFilter: 'date', width: '15%', enableFiltering: false }
]
};

$http.get('/data/500_complex.json')
.success(function(data) {
$scope.gridOptions.data = data;
$scope.gridOptions.data[0].age = -5;

data.forEach( function addDates( row, index ){
row.mixedDate = new Date();
row.mixedDate.setDate(today.getDate() + ( index % 14 ) );
row.gender = row.gender==='male' ? '1' : '2';
});
});
}])

.filter('mapGender', function() {
var genderHash = {
1: 'male',
2: 'female'
};

return function(input) {
if (!input){
return '';
} else {
return genderHash[input];
}
};
})

.directive('myCustomDropdown', function() {
return {
template: '<select class="form-control" ng-model="colFilter.term" ng-options="option.id as option.value for option in colFilter.options"></select>'
};
});
</file>
<file name="index.html">
<div ng-controller="MainCtrl">
<div id="grid1" ui-grid="gridOptions" class="grid"></div>
</div>
</file>
<file name="main.css">
.grid {
width: 650px;
height: 400px;
}
.modalGrid1 {
width: 100px;
height: 200px;
}
.modal-dialog1 {
width: 150px;
}
</file>
<file name="scenario.js">
var gridTestUtils = require('../../test/e2e/gridTestUtils.spec.js');
</file>
</example>
92 changes: 92 additions & 0 deletions src/features/multi-select-filter/js/ui-grid-multiselect-filter.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
(function(){
'use strict';
angular.module('ui.grid.multiselect.filter', ['ngAnimate', 'ngTouch', 'ui.grid', 'ui.grid.selection'])
.controller('multiSelectCtrl', ["$scope", "$compile", "$timeout", "$element", "$attrs", "$parse", function($scope, $compile, $timeout, $element, $attrs, $parse) {
var $elm;
var col = $scope.col;
var childScope;
$scope.colFilter = $scope.col.filters[0];
$scope.title = col.field;
$scope.showModal = function() {
$scope.listOfTerms = [];
$scope.col.grid.options.data.forEach(function(row) {
if ($scope.listOfTerms.indexOf(row[col.field]) === -1) {
$scope.listOfTerms.push(row[col.field]);
}
});
$scope.listOfTerms.sort();
$scope.gridOptions = {
data: [],
enableColumnMenus: false,
onRegisterApi: function(gridApi) {
$scope.gridApi = gridApi;

if ($scope.colFilter && $scope.colFilter.listTerm) {
$timeout(function() {
$scope.colFilter.listTerm.forEach(function(cellData) {
var entities = $scope.gridOptions.data.filter(function(row) {
return row[col.field] === cellData;
});

if (entities.length > 0) {
$scope.gridApi.selection.selectRow(entities[0]);
}
});
});
}
}
};

$scope.listOfTerms.forEach(function(cellData) {
var r = {};
r[col.field] = cellData;
$scope.gridOptions.data.push(r);
});

var html = '<div class="ui-grid-multi-select-filter"><div class="header">Filter {{title}}</div><div class="modal-body"><div class="multi-select-grid" ui-grid="gridOptions" ui-grid-selection></div></div><div class="footer"><button class="btn-close" ng-click="close()">Filter</button><button class="btn-close" ng-click="cancel()">Cancel</button></div></div>';
$elm = angular.element(html);
angular.element($element[0].closest('div[ui-grid]')).append($elm);

childScope = $scope.$new();
$compile($elm)(childScope);
};

$scope.cancel = function() {
if ($elm) {
childScope.$destroy();
$elm.remove();
}
};

$scope.close = function() {
var trems = $scope.gridApi.selection.getSelectedRows();
$scope.colFilter.listTerm = [];

trems.forEach(function(row) {
var t = row[col.field];
if (typeof t === "string") {
t = t.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&");
}
$scope.colFilter.listTerm.push(t);
});

$scope.colFilter.term = $scope.colFilter.listTerm.join(', ');
$scope.colFilter.condition = new RegExp($scope.colFilter.listTerm.join('|'));

if ($elm) {
childScope.$destroy();
$elm.remove();
}

$parse($attrs.onFilter)($scope, {
$terms: $scope.colFilter.listTerm
});
};
}])
.directive('multiSelectFilter', function() {
return {
template: '<button class="ui-grid-multiselect-btn" ng-class="{filtered: colFilter.listTerm.length > 0}" ng-click="showModal()">...</button>',
controller: 'multiSelectCtrl'
};
});
})();
29 changes: 29 additions & 0 deletions src/features/multi-select-filter/less/multiselect-filter.less
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
.ui-grid-multi-select-filter {
position: absolute;
left: 36%;
top: 10%;
width: 28%;
z-index: 999;
background: #FDFDFD;
border: 1px solid #d4d4d4;
padding: 1%;
box-shadow: 2px 2px 3px #d4d4d4;
}

.ui-grid-multi-select-filter .header {
font-size: 15px;
font-weight: bold;
margin-bottom: 5px;
text-transform: capitalize;
}

.ui-grid-multi-select-filter .footer button {
float: right;
margin-top: 5px;
margin-left: 5px;
}

.ui-grid-multiselect-btn.filtered {
background-color: #c9dde1;
font-weight: bold;
}