Forum Stats

  • 3,757,798 Users
  • 2,251,267 Discussions


Filtering BufferingDataProvider Without Losing Edits

DaveArch Member Posts: 102 Red Ribbon

JET Version: 10.0

Hi JET Community

We have the need to use BufferingDataProvider with oj-table to buffer edits that the user makes in conjunction with being able to filter that data without losing the buffered edits.

The use case is that we have a parent-child tableàtable where selecting the parent filters the child table. All child data is fetched in a network call at the beginning of the page loading i.e. the children for all of the parent rows is fetched at once (small data sets). We need to be able to populate the BufferingDataProvider with all of the child data and then filter it when a user selects a parent. That bit is relatively straight forwards as we wrap a ListDataProviderView in the BufferingDataProvider and filter it as so:

this.childDataProvider = ko.observable();
let filterCriteria = {
   op: '$or',
   criteria: [
           op: '$eq', value:
               { parentId: id } // id being the parent record unique id

let listDataProvider = new ListDataProviderView(childArrayDataProvider, { filterCriterion: filterCriteria }); // childArrayDataProvider being the ArrayDataProvider holding all of the child records

this.childDataProvider(new BufferingDataProvider(listDataProvider)); // Replace the data provider bound to the child table

Here’s the problem…..

When a user selects a parent and then inserts/updates or deletes a child row, these changes are tracked by the BufferingDataProvider. The problem is that when a user selects another row, we are creating a new ListDataProviderView with the new filter and updating the BufferingDataProvider for the child table and therefore the changes are lost for the original child rows.

Now, we could capture the submitted items from BufferingDataProvider before filtering each time and store them for committing later however what if a user navigates back to the original parent row? Those previous edits would need to be re-applied which gets very messy.

So my question is, how do we filter a BufferingDataProvider and keep any edits between filtering i.e. how do we populate BufferingDataProvider once and filter it without replacing it in each filter action.

Both examples in the Cookbook for table filtering and ListDataProviderView replace the data provider each time the filter is applied which causes the above issue in the case of buffered edits.

Any help always appreciated.



  • Christine Lei-Oracle
    Christine Lei-Oracle Member Posts: 6 Employee
    edited Sep 16, 2021 7:17PM

    Have you tried to wrap the child data the other way around as

    const bufferingDP = new BufferingDataProvider(childArrayDataProvider);
    this.childDataProvider(new ListDataProviderView(bufferingDP));

    Hopefully in this way, ListDataProviderView would apply filter on all buffered data.

  • DaveArch
    DaveArch Member Posts: 102 Red Ribbon

    Thanks for your reply Christine.

    Unfortunately that doesn’t work because wrapping it the other way around means that the functions specific to BufferingDataProvider are not available i.e. getSubmittableItems()

    node.js:3173 Uncaught TypeError: this.childDataProvider(...).getSubmittableItems is not a function

    Any other ideas?

    Is there a way of altering the filterCriterion on ListDataProviderView without replacing the whole data provider which is wrapping it?  I was wondering whether this would work so that they next time the data is fetched it will use the new filter?

  • Christine Lei-Oracle
    Christine Lei-Oracle Member Posts: 6 Employee

    The original wrapping order will use original data without buffered data information. Don't seem to have a way better than your current one although it's not that 'automatic' unfortunately.