Comments (11)
Hi,
To set a filter you can use the setFilter
method in PblDataSource
:
setFilter(value: DataSourceFilterToken, columns: PblColumn[]): void;
The token can be:
export type DataSourceFilterToken = undefined | DataSourcePredicate | any;
With any
being a value to compare to, which will automatically compare the values in the columns
provided into the value you provided to the filter.
For a more fine-grained control, you can use DataSourcePredicate
export type DataSourcePredicate = (item: any, properties: PblColumn[]) => boolean;
The predicate function will get the item
which is the row and the list of columns to filter by.
You can use PblColumn.getValue(item)
to get the actual value of each column for the provided row (item
).
You can see how the internal implementation handles this, when the filter is a value
and not a predicate
here
There is another way to filter, by instruction the datasource to skip handling the filter functionality and so it can be passed to the datasource trigger handler, with the factory it should look like this:
const dsCustomTrigger = createDS<Person>()
.setCustomTriggers('filter')
.onTrigger( event => {
if (event.filter.changed) {
const filter = event.filter.curr; // <- Current filter, type: DataSourceFilter
/* HANDLE FILTER CHANGES HERE IT */
}
})
.create();
You can set more custom trigger, the full list is
.setCustomTriggers('filter', 'pagination', 'sort')
This type of handling filters is more suitable when the filter/sort/pagination is handled at the server-side and not for actually handling client side filtering, for that I suggest using the predicated.
However, If you want to read more about the triggers, you can find info here. The event
object can tell you the source of the trigger, which is one of: sort, pagination, filter, refresh()
call or the initial call to get data.
With that being said, I do thing that the filter & sort API should get some API re-work to improve how users use them...
from ngrid.
@shlomiassaf thanks for your information! I will try that out later.
There was one more thing I noticed after playing around with setFilter
.
Apparently, it is not easily possible to get the result of a filter operation, but I guess I am just missing something.
MatTableDataSource was able to use filteredData()
, returning
The filtered set of data that has been matched by the filter string, or all the data if there is no filter
So, after using applyFilter()
, how to get the filtered data?
PblDataSource.filter()
as well as the corresponding behavior subject only return the filter types, the parent class DataSource
from CDK is abstract does not implement any functions :-/
from ngrid.
@tsiegleauq I'm afraid that currently it's not possible using the built-in implementation.
I'll explain:
The entire datasource is built out of 2 units.
- PblDataSource
- PblDataSourceAdapter
The datasource (PblDataSource
) require an adapter (PblDataSourceAdapter
) to work. The datasource is just a container and the adapter does all the logical work, including calling the handler provided by the user to fetch data.
This way it's easy for the user to work with data, just use the factory function (createDS
) and return an Array / Promise / Observable.
The adapter has to take care of 4 triggers:
- Filtering
- Sorting
- Paging
- Refresh
The library comes with a built in adapter that know's how to handle all of the triggers for the client side scenario, e.g. filtering on the current source, sorting on it, etc...
The factory createDS
is just a helper that abstract the process of creating a new datasource and new adapter, it bind the built-in adapter with the datasource.
The built-in adapter is smart enough to allow manually handling of the triggers. For example, if you want to sort on the server side the adapter will skip that trigger and let the user manually handle it in the handler he provides.
One can always implement his own adapter, for example, if a server implements the OData
protocol, such an adapter can be built which will convert all filters, sorting and pagination based on that.
Now, about your question, you refer to filtering but it might also relate to the sorted result etc...
From the adapter's perspective there might not be a filtered result, if the user has chosen to manually handle that trigger.
In addition, if the filtered result is saved and sort is also set, is it saved with sorting? and vice versa does sorted results get saved with or without filtering?
If both filtering and sorting are set it requires re-running them, but now if just filtering is changed should we cache the previous sorting and run the filtering on it or run the sort and filter again?
And what about performance? saving the sorted results, filtered results and all of the results of a 100,000 rows dataset, isn't it an issue?
With large datasets this has a huge impact.
I'm not ruling this out, just trying to think what's the best approach here.
BTW, you can always set a manually trigger on the
filter
and run applyFilter on the sport within the trigger handler
from ngrid.
I see. Well, displaying sorted and filtered data in a table is nice to have, but I suppose getting the filtered (and sorted) data (in code) is a pretty common use case.
A relatable way could be to use the table component to get the rusult of the sorting and filtering. Perhaps something like a "rowAPI" similar to the column API could be required.
Do you have a suggestion to tackle this?
from ngrid.
I have the sorted data already store in the adapter and I could probably store the filtered data as well...
If both sort and filter are applied the filtered data will be sorted as well, filtering comes after sort.
The question is, will it cause a performance issue if the dataset is large? a 100k rows dataset with sort is now 200k, add in a filter that has O(N) of 200k you get to 3 arrays of 300k rows (ofcourse all objects are shared but still)
The reason I store the sort results is to support fast filtering without re-sorting on each filter hit... Filtering might be time consuming, depending on implementation, and it might happen rapidly (keyboard typing) so I want to cache what I can.
Perhaps we can support an API that will emit the result of filter and sort so users can hook into them if they wish... of course this will require the emission of cloned arrays... but I can live with that.
Thoughts?
from ngrid.
There are pros and cons to ever solution. If you filter before sorting, your N will be smaller, but sorting then needs to happen again, after the filter changed.
To implement fast filtering with keyboard typing, some rxjs magic to add a "debounce time" before filtering should do the trick.
from ngrid.
@shlomiassaf, thank you for a great work, it's a fantastic package!
i have a set of filters which i need to implement:
-two columns by input text
-another by mat list selection (if column value is in selection list)
-another may be by datepicker (if columns value is in selected period)
i guess it could be done by using filterPredicate, however i really struggle with implementing this solution. Is there any example I could find?
thanks in advance!
from ngrid.
@ek2dev
You will have to use the filter predicate for this.
The filtering predicate returns a boolean value true/false given the row and columns.
Notice the input, its the row not the value of a cell.... the columns are those you set to filter by and with each column/row pair can yield the value which with you can filter.
Now, because the filter returns a predicate you can return true
on the first result hit, if no hit then try searching again with the next value from the next component (e.g. mat-select) and so on until no more things to search by exist. This will be an "OR" like search, you can do an "AND" search as well.. you choose the logic.
For example, I have an input box and a selection box stored in the params inputValue
and selectedValue
on the component class.
Every time the input or select change the values are updated and I can react to the change.
The filter API is not perfect, it works fine for the basic usage, providing a value and filtering by it.
It requires some work for custom predicates, for example, now it not straight forward to run the filter again, unless you provide a new filter predicate which is not the right approach.
I will fix this and post a message here with an example, once done.
from ngrid.
@ek2dev Now in 1.0.0-alpha.16
See example here
from ngrid.
that worked.
thanks a lot!
from ngrid.
Fully implemented, read Features -> Column -> Column Filters page for more information.
from ngrid.
Related Issues (20)
- [Bug] material `define-...-theme` edits theme too excessive
- pbl-ngrid throwing error when changing pages on Angular project. HOT 2
- When using vScrollNone, grid is not visible when container has height unset or set to auto
- Infinite-scroll TS compile error
- Angular 13 support HOT 3
- In version 4.0 createRowEvent function sometimes crashes due to event.context == null HOT 9
- Allow positioning the paginator in the "outer top" section above the grid
- Cannot resolve type entity i31.ScrollingModule to symbol HOT 2
- Sticky columns set through directive cannot be "un-sticked" HOT 1
- In ngrid 5.0.0 resolving of PblNgridCellFactoryResolver fails in createComponent() HOT 7
- ag-grid like filter popup with ngrid
- Undefined rowContext on scroll and cell focus is not correct
- Wrong context row data in TargetEventsPlugin with vScrollAuto and RouteReuseStrategy
- invalidateColumns breaks other tables when used with RouteReuseStrategy
- columnResize subscription
- Issue double clicking column header border to 'resize' to content width HOT 1
- Dynamic template based on column configuration
- PblNgridCellEvent rowIndex not matching _rowIndex inside PblNgridRowComponent
- Getting started HOT 1
- Compatibility with Angular 16/17
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from ngrid.