Reputation: 19
I have implemented the single filter with ui grid as said in doc. http://ui-grid.info/docs/#/tutorial/321_singleFilter
But I have a cellFilter and when I filter, it filters on data, not rendered data with filter. Which is wrong for end user.
For instance, on this plunker I would like to filter on 'male' or 'female' input.
http://plnkr.co/edit/TNJSlc0QkBI8Tu2Jejam?p=preview
var app = angular.module('app', ['ngTouch', 'ui.grid']);
app.controller('MainCtrl', ['$scope', '$http', function ($scope, $http) {
var today = new Date();
$scope.gridOptions = {
enableFiltering: false,
onRegisterApi: function(gridApi){
$scope.gridApi = gridApi;
$scope.gridApi.grid.registerRowsProcessor( $scope.singleFilter, 200 );
},
columnDefs: [
{ field: 'name' },
{ field: 'gender', cellFilter: 'mapGender' },
{ field: 'company' },
{ field: 'email' },
{ field: 'phone' },
{ field: 'age' },
{ field: 'mixedDate' }
]
};
$http.get('https://cdn.rawgit.com/angular-ui/ui-grid.info/gh-pages/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';
});
});
$scope.filter = function() {
$scope.gridApi.grid.refresh();
};
$scope.singleFilter = function( renderableRows ){
var matcher = new RegExp($scope.filterValue);
renderableRows.forEach( function( row ) {
var match = false;
[ 'name', 'company', 'email', 'gender' ].forEach(function( field ){
//row.entity[field] for gender col is 1 or 2 instead of male or female
if ( row.entity[field].match(matcher) ){
match = true;
}
});
if ( !match ){
row.visible = false;
}
});
return renderableRows;
};
}])
.filter('mapGender', function() {
var genderHash = {
1: 'male',
2: 'female'
};
return function(input) {
if (!input){
return '';
} else {
return genderHash[input];
}
};
});
Upvotes: 1
Views: 1320
Reputation: 629
There is an option for cells called filterCellFiltered
, which you can apply to your columnDefs:
{ field: 'gender', cellFilter: 'mapGender', filterCellFiltered: true },
uiGrid will then apply the cellFilter before applying "search" filters. Unfortunately this option only works for columnFilters. But we can still use it in our singleFilter code to check whether we want to match against the normal or the filtered value.
Not sure if this is the best way to do it, but here is my solution:
$scope.singleFilter = function( renderableRows ){
var matcher = new RegExp($scope.filterValue);
renderableRows.forEach( function( row ) {
var match = false;
row.grid.columns.forEach(function( column ){
// get the filtered value, if filterCellFiltered option is set
var value;
if ( column.filterCellFiltered ){
value = row.grid.getCellDisplayValue(row, column);
} else {
value = row.grid.getCellValue(row, column);
}
if ( value.toString().match(matcher) ){
match = true;
}
});
if ( !match ){
row.visible = false;
}
});
return renderableRows;
};
Upvotes: 2