Our blazing fast Grid component built with pure JavaScript


Post by dylan.sheffer »

We are using remote filtering and sorting on our AjaxStore and we are seeing a poor API and user experience because every event triggers a new network request. For example, a user will type a string into the filter and each character will launch an API request. The result is the user will get out of order responses resulting in older requests overwriting newer requests.

This is especially frustrating for our users because their filters behaving unpredictably and it is putting unnecessary strain on our API because it dramatically increases the number of API requests.

We would like to add a debounce on these requests until the user stops typing. We have tried adding a buffer to the beforeRequest event, but it merely puts a buffer on the anonymous function we pass it instead of the actual network requests.

Do you have any suggestions on how to accomplish this? Our only thought is to drop the AjaxStore entirely and write our own wrapper around the regular Store.

Example Code:

this.ajaxStore.on(
          {
          beforeRequest: () => console.log("before request fired"),
          buffer: 2000
        }
      );

Post by Maxim Gorkovsky »

Hello.
I suppose problem could be that you call filter as user types in:

new Grid({
  tbar: [{ type: 'textfield', onChange({ value }) { grid.store.filter('field', value); } }]
})

You should delay call to a filter, not delaying requests triggered by filter. If you're using our widget for text field you can try this config: https://bryntum.com/docs/grid/api/Core/widget/Field#config-keyStrokeChangeDelay


Post by robcook@everactive »

I'm on the team with Dylan and jumping in while he is busy on other things.

We're not using the tbar of the grid for our implementation. We are marking columns as filterable

vue setup w/ @bryntum/grid-vue module

<bryntum-grid
  :ref="refName"
  :key="gridKey"
  :columns="columns"
  :rowHeight="50"
  :searchFeature="false"
  :filterBarFeature="true"
  :cellEditFeature="false"
  :cellMenuFeature="cellMenuOptions"
  :headerMenuFeature="headerMenuOptions"
  :groupFeature="false"
  :regionResizeFeature="true"
  :sortFeature="true"
  :readOnly="true"
  :store="ajaxStore"
/>

columns are generated with this:

get columns() {
  return [
    {
        id: "id",
        field: "id",
        text: "ID",
        exportedType: "string",
        width: 340,
        hidden: true,
        sortable: false,
        filterable: false
      },
      {
        id: "name",
        field: "name",
        text: "Name",
        exportedType: "string",
        width: 200,
        hidden: false,
        sortable: true,
        filterable: true,
      },
  ]
}

The AjaxStore is setup with the readUrl set and the autoLoad property set to false.

const ajaxStore = new AjaxStore({
  readUrl: {{the read url endpoint}},
  autoLoad: false,
  filterParameterName: "filter"
  pageParameterName: "page",
  pageSizeParamName: "pageSize",
});

The name column is rendered with a text box in the column header. Each character typed in the text box modifies the filter immediately firing off an ajax API call from the AjaxStore. I tried setting a keyStrokeChangeDelay property on the name column but this does not appear to have any effect on the rate of API calls.

Is there a property on the column, grid or ajaxstore that will allow us to debounce the rate the filters are applied? We have not been able to find anything looking through the documentation that appears to effect this behavior.


Post by mats »

Please see https://bryntum.com/docs/scheduler/api/Grid/feature/FilterBar#config-keyStrokeFilterDelay

/**
             * The delay in milliseconds to wait after the last keystroke before applying filters.
             * Set to 0 to not trigger filtering from keystrokes, requires pressing ENTER instead
             * @config {Number}
             * @default
             * @category Common
             */
            keyStrokeFilterDelay : 300,

Post by robcook@everactive »

@mats - thanks for the reply. Setting this using grid.features.filterBar.keyStrokeFilterDelay = 300; did not work. However if I set each individual column with an object for filterable it does work:

{
        id: "name",
        field: "name",
        text: "Name",
        exportedType: "string",
        width: 200,
        hidden: false,
        sortable: true,
        filterable: {
          filterField: {
            keyStrokeChangeDelay: 300
          }
        }
      },

Thanks again for pointing us in the right direction.


Post by mats »

Seems to work fine for me, trying at https://bryntum.com/examples/grid/filterbar/

Glad you have it working! :)


Post Reply