Skip to content

Commit 1616164

Browse files
committed
feat(filtering): Add row filtering
1 parent 1fad1ff commit 1616164

27 files changed

+1051
-141
lines changed

Gruntfile.js

+5-5
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ module.exports = function(grunt) {
1616
'<%= grunt.template.today("yyyy-mm-dd") %>\n' +
1717
'<%= pkg.homepage ? "* " + pkg.homepage + "\\n" : "" %>' +
1818
'* Copyright (c) <%= grunt.template.today("yyyy") %> <%= pkg.author.name %>;' +
19-
' Licensed <%= pkg.license %> */\n',
19+
' License: <%= pkg.license %> */\n',
2020

2121
shell: {
2222
options: {
@@ -418,12 +418,12 @@ module.exports = function(grunt) {
418418
},
419419
scripts: [
420420
'//ajax.googleapis.com/ajax/libs/jquery/2.0.3/jquery.min.js', // TODO(c0bra): REMOVE!
421-
'//ajax.googleapis.com/ajax/libs/angularjs/1.2.15/angular.js',
422-
'//ajax.googleapis.com/ajax/libs/angularjs/1.2.15/angular-touch.js',
423-
'//ajax.googleapis.com/ajax/libs/angularjs/1.2.15/angular-animate.js',
421+
'//ajax.googleapis.com/ajax/libs/angularjs/1.2.16/angular.js',
422+
'//ajax.googleapis.com/ajax/libs/angularjs/1.2.16/angular-touch.js',
423+
'//ajax.googleapis.com/ajax/libs/angularjs/1.2.16/angular-animate.js',
424424
],
425425
hiddenScripts: [
426-
'//ajax.googleapis.com/ajax/libs/angularjs/1.2.15/angular-animate.js',
426+
'//ajax.googleapis.com/ajax/libs/angularjs/1.2.16/angular-animate.js',
427427
'bower_components/google-code-prettify/src/prettify.js',
428428
'node_modules/marked/lib/marked.js'
429429
],

TODO.md

+15-4
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,24 @@
11
# TODO
22

3-
# CURRENT
3+
# CURRENT (row filtering)
4+
5+
1. [TODO] - Make 'No Rows' message i18n
6+
1. [BUG] - i18n causes an exception if a given value is not present.
7+
1. I think we need a function that will look for a translation in the current or given language and then return the value for the default language if not present
8+
1. It could also take a flag and return null if not present
9+
1. Need to add a test for this...
10+
11+
1. [TODO] - Does rowSearcher need to allow for custom equality comparators in colDef?
12+
1. [IDEA] - Should RegExps be allowed as search terms? We could test for whether the filter value starts and ends with '/'
13+
14+
1. [TODO] - Document the autoHide feature for uiGridMenu. Probably need to rename it to hideOnResize
415

516
1. [TODO] - Does rowsProcessors make sense for external sorting??? It would be downstream from the rows being added/modified, and would ITSELF be modifying the rows...
617
1. Would probably be an infinite loop. External sorting needs to be able to hook in further upstream.
18+
1. Sorting a column prompts a call to refreshRows(). Could we have a hook in there to run BEFORE rowsProcessors?
719

820
1. [TODO] - Do rows processors need to be able to modify the count of of rows? As it is the documentation says the count needs to stay the same... but searching would affect that
921

10-
1. [BUG] - Do we need to validate passed in grid 'id' property to make sure it can be in a CSS rule?
1122
1. [IDEA] - Hook the column menu button into the menu it activates so it can show/hide depending on the number of items it will show. Can we do that?
1223
1. If sorting is enabled or the user / extension has supplied extra menu items, show the menu button. Otherwise don't show it.
1324
1. We'll need a way to separate extension menu items from user menu items so the user doesn't override them.
@@ -31,20 +42,20 @@
3142
1. [NOTE] - Use "-webkit-text-stroke: 0.3px" on icon font to fix jaggies in Chrome on Windows
3243
1. [TODO] - Add a failing test for the IE9-11 column sorting hack (columnSorter.js, line 229)
3344

34-
1. [TODO] - Add row filtering
3545
1. [TODO] - Add notes about browser version support and Angular version support to README.md
3646
1. [TODO] - Add handling for sorting null values with columnDef sortingAlgorithm (PR #940)
3747
1. [TODO] - Currently uiGridColumnMenu uses i18n to create the menu item text on link. If the language is changed, they won't update because they're not bound...
3848

3949
# Cleanup
4050

51+
1. [TODO] - Remove commented-out dumps from gridUtil
4152
1. [TODO] - Rename gridUtil to uiGridUtil
4253
1. [TODO] - Rename GridUtil in uiGridBody to gridUtil or the above
4354
1. [TODO] - Move uiGridCell to its own file
4455

4556
# Extras
4657

47-
1. Add iit and ddescribe checks as commit hooks
58+
<!-- 1. Add iit and ddescribe checks as commit hooks -->
4859

4960
# Native scrolling
5061

misc/tutorial/5.1.1_Filtering.ngdoc

+44
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
@ngdoc overview
2+
@name Tutorial: Filtering
3+
@description
4+
5+
UI-Grid allows you to filter rows. Just set the `enableFiltering` flag in your grid options (it is off by default).
6+
7+
Sorting can be disabled at the column level by setting `enableFiltering: false` in the column def. See the last column below for an example.
8+
9+
@example
10+
<example module="app">
11+
<file name="app.js">
12+
var app = angular.module('app', ['ngAnimate', 'ui.grid']);
13+
14+
app.controller('MainCtrl', ['$scope', '$http', function ($scope, $http) {
15+
$scope.gridOptions = {
16+
enableFiltering: true,
17+
columnDefs: [
18+
{ field: 'name' },
19+
{ field: 'gender' },
20+
{ field: 'company', enableFiltering: false }
21+
]
22+
};
23+
24+
$http.get('/data/100.json')
25+
.success(function(data) {
26+
$scope.gridOptions.data = data;
27+
});
28+
}]);
29+
</file>
30+
<file name="index.html">
31+
<div ng-controller="MainCtrl">
32+
Click on a column header to open the menu and then filter by that column. (The third column has filtering disabled.)
33+
<br>
34+
<br>
35+
<div ui-grid="gridOptions" class="grid"></div>
36+
</div>
37+
</file>
38+
<file name="main.css">
39+
.grid {
40+
width: 500px;
41+
height: 400px;
42+
}
43+
</file>
44+
</example>

misc/tutorial/5.1_sorting.ngdoc

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
@name Tutorial: Sorting
33
@description
44

5-
UI-Grid allows you to sort rows. Just set the `enableSorting` flag in your grid options.
5+
UI-Grid allows you to sort rows. The feature is on by default. You can set the `enableSorting` flag in your grid options to enable/disable it.
66

77
<span class="span8 alert alert-warning">
88
<strong>Note:</strong> You must include ngAnimate in your application if you want the menu to slide up/down, but it's not required.

src/font/config.json

+6
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,12 @@
66
"units_per_em": 1000,
77
"ascent": 850,
88
"glyphs": [
9+
{
10+
"uid": "9dd9e835aebe1060ba7190ad2b2ed951",
11+
"css": "search",
12+
"code": 59407,
13+
"src": "fontawesome"
14+
},
915
{
1016
"uid": "5211af474d3a9848f67f945e2ccaf143",
1117
"css": "cancel",

src/js/core/constants.js

+11
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,17 @@
5151
},
5252
ASC: 'asc',
5353
DESC: 'desc',
54+
filter: {
55+
STARTS_WITH: 2,
56+
ENDS_WITH: 4,
57+
EXACT: 8,
58+
CONTAINS: 16,
59+
GREATER_THAN: 32,
60+
GREATER_THAN_OR_EQUAL: 64,
61+
LESS_THAN: 128,
62+
LESS_THAN_OR_EQUAL: 256,
63+
NOT_EQUAL: 512
64+
},
5465

5566
// TODO(c0bra): Create full list of these somehow. NOTE: do any allow a space before or after them?
5667
CURRENCY_SYMBOLS: ['ƒ', '$', '£', '$', '¤', '¥', '៛', '₩', '₱', '฿', '₫']

src/js/core/directives/ui-grid-column-menu.js

+28-2
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,34 @@ angular.module('ui.grid').directive('uiGridColumnMenu', ['$log', '$timeout', '$w
4141
return false;
4242
}
4343
}
44+
45+
function filterable() {
46+
if (uiGridCtrl.grid.options.enableFiltering && typeof($scope.col) !== 'undefined' && $scope.col && $scope.col.enableFiltering) {
47+
return true;
48+
}
49+
else {
50+
return false;
51+
}
52+
}
4453

4554
var defaultMenuItems = [
55+
// NOTE: disabling this in favor of a little filter text box
56+
// Column filter input
57+
// {
58+
// templateUrl: 'ui-grid/uiGridColumnFilter',
59+
// action: function($event) {
60+
// $event.stopPropagation();
61+
// $scope.filterColumn($event);
62+
// },
63+
// cancel: function ($event) {
64+
// $event.stopPropagation();
65+
66+
// $scope.col.filter = {};
67+
// },
68+
// shown: function () {
69+
// return filterable();
70+
// }
71+
// },
4672
{
4773
title: i18nService.get().sort.ascending,
4874
icon: 'ui-grid-icon-sort-alt-up',
@@ -199,12 +225,12 @@ angular.module('ui.grid').directive('uiGridColumnMenu', ['$log', '$timeout', '$w
199225

200226
$scope.$on('$destroy', $scope.$on(uiGridConstants.events.GRID_SCROLL, function(evt, args) {
201227
self.hideMenu();
202-
if (! $scope.$$phase) { $scope.$apply(); }
228+
// if (! $scope.$$phase) { $scope.$apply(); }
203229
}));
204230

205231
$scope.$on('$destroy', $scope.$on(uiGridConstants.events.ITEM_DRAGGING, function(evt, args) {
206232
self.hideMenu();
207-
if (! $scope.$$phase) { $scope.$apply(); }
233+
// if (! $scope.$$phase) { $scope.$apply(); }
208234
}));
209235

210236
$scope.$on('$destroy', function() {

src/js/core/directives/ui-grid-header-cell.js

+24-3
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ angular.module('ui.grid').directive('uiGridHeaderCell', ['$log', '$timeout', '$w
2727
// Store a reference to menu element
2828
var $colMenu = angular.element( $elm[0].querySelectorAll('.ui-grid-header-cell-menu') );
2929

30+
var $contentsElm = angular.element( $elm[0].querySelectorAll('.ui-grid-cell-contents') );
31+
3032
// Figure out whether this column is sortable or not
3133
if (uiGridCtrl.grid.options.enableSorting && $scope.col.enableSorting) {
3234
$scope.sortable = true;
@@ -35,6 +37,13 @@ angular.module('ui.grid').directive('uiGridHeaderCell', ['$log', '$timeout', '$w
3537
$scope.sortable = false;
3638
}
3739

40+
if (uiGridCtrl.grid.options.enableFiltering && $scope.col.enableFiltering) {
41+
$scope.filterable = true;
42+
}
43+
else {
44+
$scope.filterable = false;
45+
}
46+
3847
function handleClick(evt) {
3948
// If the shift key is being held down, add this column to the sort
4049
var add = false;
@@ -53,7 +62,7 @@ angular.module('ui.grid').directive('uiGridHeaderCell', ['$log', '$timeout', '$w
5362
// Long-click (for mobile)
5463
var cancelMousedownTimeout;
5564
var mousedownStartTime = 0;
56-
$elm.on('mousedown', function(event) {
65+
$contentsElm.on('mousedown', function(event) {
5766
if (typeof(event.originalEvent) !== 'undefined' && event.originalEvent !== undefined) {
5867
event = event.originalEvent;
5968
}
@@ -72,7 +81,7 @@ angular.module('ui.grid').directive('uiGridHeaderCell', ['$log', '$timeout', '$w
7281
});
7382
});
7483

75-
$elm.on('mouseup', function () {
84+
$contentsElm.on('mouseup', function () {
7685
$timeout.cancel(cancelMousedownTimeout);
7786
});
7887

@@ -101,7 +110,7 @@ angular.module('ui.grid').directive('uiGridHeaderCell', ['$log', '$timeout', '$w
101110

102111
// If this column is sortable, add a click event handler
103112
if ($scope.sortable) {
104-
$elm.on('click', function(evt) {
113+
$contentsElm.on('click', function(evt) {
105114
evt.stopPropagation();
106115

107116
$timeout.cancel(cancelMousedownTimeout);
@@ -123,6 +132,18 @@ angular.module('ui.grid').directive('uiGridHeaderCell', ['$log', '$timeout', '$w
123132
$timeout.cancel(cancelMousedownTimeout);
124133
});
125134
}
135+
136+
if ($scope.filterable) {
137+
$scope.$on('$destroy', $scope.$watch('col.filter.term', function(n, o) {
138+
uiGridCtrl.refreshRows()
139+
.then(function () {
140+
if (uiGridCtrl.prevScrollArgs && uiGridCtrl.prevScrollArgs.y && uiGridCtrl.prevScrollArgs.y.percentage) {
141+
uiGridCtrl.fireScrollingEvent({ y: { percentage: uiGridCtrl.prevScrollArgs.y.percentage } });
142+
}
143+
// uiGridCtrl.fireEvent('force-vertical-scroll');
144+
});
145+
}));
146+
}
126147
}
127148
};
128149

0 commit comments

Comments
 (0)