Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AngularJS ng-grid filter -- filterText format

I am using the AngularJS ng-grid (v2.0.7 v2.0.8) and I would like to understand the syntax for the filterText field in the API.

In particular I would like to know how to filter on a specific column or columns, and filter one or more entries in a column.

There are many stack overflow questions with tags ng-grid and filter, and while they are useful, one that gives a full summary of the filterText format is not currently available.

like image 382
JayInNyc Avatar asked Dec 06 '13 21:12

JayInNyc


2 Answers

At the time of this writing there is no summary on how to construct the 'filterText' string in general. After studying the ng-grid.js code and making some guesses I have found that 'filterText' is much more powerful and expressive than the current documentation suggests.

Example Setup

To set up the answer, first consider a grid with the following definition, located in some controller:

  $scope.pricing_data = data['records'];

  $scope.gridOptions = { 
    data: 'pricing_data',
    columnDefs: [
      { field: 'ticker', displayName: 'Ticker' },
      { field: 'date',   displayName: 'Date'   },
      { field: 'close',  displayName: 'Close'  },
      { field: 'volume', displayName: 'Volume' }
    ],
    filterOptions: {filterText: '', useExternalFilter: false},
    showFilter: true
  };

The object at data['records'] can be some json object sent from the backend. A sample table might look like this:

an unfiltered table

As it stands, filterText is blank so all records are presented.

The down carrot in the upper right of the grid is visible because showFilter is true. Clicking on the down carrot shows an input that is bound to the variable 'filterText'. For this discussion I'll show some results using this dropdown, but generally you can directly assign to filterText in your controller code. The dropdown looks like this:

showFilter widget bound to filterText

Search All Fields in Grid

By default, filterText executes a regex against every cell in the grid. Typing in the character 'a' selects all records that have the character 'a' in any entry (or column) of that record. Typing 'ab' selects all records that have the character sequence 'ab' in any entry of that record. Depending on your requirements, this behavior may be perfectly suitable. However, with large data sets, one typically wants to filter on columns rather than the whole grid because of the nature of the data (e.g. select a price ticker) and because of the high cost of searching the whole grid.

Search By Column

In order to search for a string or regex on just one column, the filterText syntax is:

filterText = '<displayName>:<literal>'

For instance,

first column filter

Here the displayName 'Date' (don't use the field value, you must use displayName) is followed by a colon ':' and then a partial string. The result is that only three records are selected, those associated with Oct 30th.

Let's expand the search. To search for Oct 30th or Oct 31st, the syntax is

filterText = '<displayName>:<literal 1>|<literal 2>|...'

where a pipe '|' separates each string partial. You can chain together however as many as you like. A multi-date filter might look like:

enter image description here

Clearly the selection is OR in nature. My example is not great, however, because tickers and dates have disjoint characters. So you can either trust me that only the Date column is searched or setup your own example. (Or, better still, read the buildSearchConditions() function in ng-grid, its pretty clear on this).

Search Entries in Multiple Columns

Searching multiple columns requires only a syntax extension of the search within a column. This syntax is:

filterText = '<displayName 1>:<lit 1>[|<lit 2>|..];<displayName 2>:<lit a>[|<lit b>|..][;..]'

The operative lexical element is the semicolon ';' that separates each column displayName.

Continuing on with this example, let's search for nyt or nvda on Oct 30th or Oct 31st. That looks like:

multicolumn filter 1

Logically, the filter searches (along Ticker for nyt OR nvda) AND (along Date for 10-30 OR 10-31).

Grid Updates

I am not too familiar with updates that come from cell edits. I suppose that the result is the same.

When the angular-js controller, working in conjunction with the backend, updates the grid data, then the updated data is pushed through the filter. This is a beautiful result, in effect the filter persists.

Known Bug -- Clear

At the time of this writing there is a recent fix to a known bug wherein clearing the filterText nearly or does indeed hang the browser. The report that I've followed is this one: ng-grid issue 777 . A fix was merged following ng-grid issue 848. I can definitely confirm that I see poor performance when a filter applied to a large dataset is cleared. I haven't tested the fix yet.

UPDATE

I just got around to installing ng-grid 2.0.8. The clear problem is fixed afaict. Works great.


ng-grid 3.0

ng-grid 3.0 is on the drawing board now. There is so much goodness in ng-grid 2.0 already, but like any code that's really new, a few rewrites help. I encourage the ng-grid developers to keep the filter features they have already included and perhaps extend the performance or range.

like image 140
JayInNyc Avatar answered Nov 11 '22 04:11

JayInNyc


Based on JayInNyc's answer, I did a few things to make it easier for a user to use instead of following that syntax. I basically watch any fields I want to filter for. In this case I have a input field for the name and city.

$scope.filterOptions = {
    filterText: ''
};
$scope.filterName = '';
$scope.filterCity = '';

$scope.$watch('filterName', function (value) {

    setFilterText();
});

$scope.$watch('filterCity', function (value) {

    setFilterText();
});

function setFilterText()
{
    $scope.filterOptions.filterText = 'Name: ' + $scope.filterName + ';City:' + $scope.filterCity;
}

Btw - I wanted to use the compile function, but it didnt seem to work. I had the following but it didnt work.

filterOptions.filterText = $compile('Name:{{filterName}};Category:{{filterCategory}}')(scope);

like image 25
H20rider Avatar answered Nov 11 '22 02:11

H20rider