filtrable-data-source
Utility library used to filter, paginate and sort data both client side and server side (using OData syntax). It's mainly designed to work with ngx-datatable, but it can be used with other components or stand-alone.
Table of contents
Install
NPM:
npm install filtrable-data-source
Yarn:
yarn add filtrable-data-source
Usage
Client Side
You must create a ClientFiltrableDataSource
instance and pass to it an array of elements with the setItems
method:
import { ClientFiltrableDataSource } from 'filtrable-data-source';
const myItems = [];
const dataSource = new ClientFiltrableDataSource<any>();
dataSource.setItems(myItems);
Instead of any
you can specify the type of the items in the array
Server side (OData)
You must create a ODataFiltrableDataSource
instance and pass to it a function that will be called when the data source needs to fetch new data from the server. The function takes OData parameters (top
, skip
, filter
, orderby
, count
) and returns an observable that should complete with an OData result (an object containing a count
field with the number of total items and a value
(or result
) field with array of data of the current page). To load or refresh data from server you should call the loadData
method.
import { ODataFiltrableDataSource } from 'filtrable-data-source';
const dataSource = new ODataFiltrableDataSource<any>();
this.dataSource.fetchFunction = (top, skip, count, orderby, filter) => {
};
this.dataSource.loadData();
If you have a method defined in an Angular service that have the same parameters and return type of the fetchFunction, you can pass it directly but you have to use bind
:
this.dataSource.fetchFunction = this.myService.getData.bind(this.myService);
this.dataSource.loadData();
You can set the number of item per page using the limit
property, and you can change the page with the setPage
method:
dataSource.limit = 20;
dataSource.setPage(2);
You can get the state of the pagination with the following fields:
currentItems
: array of items of the current displayed pagetotalItems
: total number of items (after filters application)page
: current pagelimit
: number of items per page
Sorting
You can use the setSort
method to apply a sorting to the data source, passing a field of the object and a sort direction
dataSource.setSort({ prop: 'name', dir: 'asc' });
Filtering
You can use the setFilter
and the removeFilter
methods to set and remove filters, the operator of the fiilter to apply is defined using utility functions (such equal
, greaterThan
, ...). After adding and removing filters you should call the applyFilters
method. You can also remove all filters at once with the resetFilters
method.
Each filter can be assigned to a specified field of the object, and also to subfields:
import { equal, greaterThan } from 'filtrable-data-source';
dataSource.setFilter('name', equal('foo'));
dataSource.setFilter('user.age', greaterThan(18));
dataSource.applyFilters();
dataSource.removeFilter('user.age');
dataSource.applyFilters();
Only one filter can be defined for a field, but you can use or
and and
operators to create a complex filter:
import { greaterThanOrEqual, lessThanOrEqual, and } from 'filtrable-data-source';
dataSource.setFilter('date', and(greaterThanOrEqual(new Date(2012, 11, 31)), lessThanOrEqual(new Date(2013, 0, 31)));
For simple filters on one field you can also use the toggleFilter
method. You should pass field name, operator, and value. When the value is undefined the filter is immediately removed, otherwise the filter is immediately applied (without the need to call applyFilters
). This method is useful for adding and removing a filter based on the value of an input
field.
dataSource.toggleFilter('name', 'contains', 'John');
dataSource.toggleFilter('name', 'contains', undefined);
List of available operators
- equal
- notEqual
- contains
- greaterThan
- greaterThanOrEqual
- lessThan
- lessThanOrEqual
- valueIn
- notValueIn
- and
- or
- not
Custom filters
You can add o remove a custom filter, if you want to filter using different logic. The definition of a custom filter is different in each implementation. If both normal filters and custom filter are defined, they will be applied in and
. The custom filter can be removed with the removeCustomFilter
method.
Client side
You can pass a function to the setCustomFilter
method that will be applied to the array of items, e.g.:
dataSource.setCustomFilter(item => item.name === 'foo' || item.age >= 18);
dataSource.applyFilters();
OData
You can pass a string as custom filter, or using the odata-filter-builder library to create a custom filter, e.g.:
import fb from 'odata-filter-builder';
dataSource.setCustomFilter(
fb
.or()
.eq('foo', 'bar')
.ne('abc', 'xyz')
);
dataSource.applyFilters();
dataSource.setCustomFilter("foo eq 'bar' or abc ne 'xyz'");
dataSource.applyFilters();
Usage with ngx-datatable
The FiltrableDataSource
exposes two methods (onTablePage
and onTableSort
) used to handle ngx-datatable
sorting and pagination. This is an example of integration:
<ngx-datatable
[columns]="columns"
[rows]="dataSource.currentItems"
[limit]="dataSource.limit"
[offset]="dataSource.page"
[count]="dataSource.totalItems"
[externalPaging]="true"
[externalSorting]="true"
(page)="dataSource.onTablePage($event)"
(sort)="dataSource.onTableSort($event)"
>
</ngx-datatable>
Migration from Git version
For converting a project using the old version of the library installed from Git, follows this steps:
- Run this command in the project root folder to find the installed version of the library:
npm ls @kalpa/filtrable-data-source
- Uninstall the library:
npm un @kalpa/filtrable-data-source
- Install the right version of the library
npm i filtrable-data-source@[[VERSION]]
(for example npm i filtrable-data-source@2.0.0
) - Run this bash script to fix the imports
find ./src -name '*.ts' -exec sed -i -e 's/@kalpa\/filtrable-data-source/filtrable-data-source/g' {} \;