Premium support for our pure JavaScript UI components


Post by H9FFDC »

Hi,

When creating a grid with columns that reference nested fields, we are unable to apply default filtering to those values. Using the code below you can filter by the 'Name' column, but any attempt to filter on 'City' or 'Postcode' will exclude all records.

let grid = new Grid({
    appendTo : 'container',

    minHeight : '20em',

    features : {
        filterBar : true
    },

    columns: [
        { field: 'name', text: 'Name', flex: 1 },
        { field: 'address.city', text: 'City', flex: 1 },
        { field: 'address.postcode',text: 'Postcode', flex: 1 }
    ],
    data: [
        {
          name: 'Bob',
          address: { city: 'Leeds', postcode: 'LS1' }
        },
        {
          name: 'Bill',
          address: { city: 'York', postcode: 'YO1' }
        }
    ]
});

Post by saki »

The default filtering only works on flat data. You can either flatten the data or you can filter using a custom https://bryntum.com/docs/grid/#Core/data/mixin/StoreFilter#function-filterBy function that would look into the object and compare deep properties.


Post by H9FFDC »

Any plans to fix this? We can sort and group by nested fields. Not being able to filter seems like a defect?


Post by saki »

Yes, it could/should be supported OOTB; the ticket is here: https://github.com/bryntum/support/issues/1861

Meanwhile you can use the following approach that works:

import '../_shared/shared.js'; // not required, our example styling etc.
import Grid from '../../lib/Grid/view/Grid.js';
import '../../lib/Grid/column/NumberColumn.js';

new Grid({
    appendTo : 'container',

    minHeight : '20em',

    features : {
        filterBar : true
    },

    columns : [
        { field : 'name', text : 'Name', flex : 1 },
        {
            field      : 'address.city',
            text       : 'City',
            flex       : 1,
            filterable : {
                filterFn : ({ record, value }) => {
                    return RegExp(value, 'i').test(record.address.city);
                }
            }
        },
        {
            field      : 'address.postcode',
            text       : 'Postcode',
            flex       : 1,
            filterable : {
                filterFn : ({ record, value }) => {
                    return RegExp(value, 'i').test(record.address.postcode);
                }
            }
        }
    ],
    data : [
        {
            name    : 'Bob',
            address : { city : 'Leeds', postcode : 'LS1' }
        },
        {
            name    : 'Bill',
            address : { city : 'York', postcode : 'YO1' }
        }
    ]
});

Post by H9FFDC »

That's great. Thanks.


Post by mats »

A better way to do this is to define your nested fields on the model directly. That's the best practise way right now:

    store      = new Store({
            fields : [{ name : 'city', dataSource : 'address.city' }],
            data   : [
                { id : 1, address : { city : 'foo' } },
                { id : 2, address : { city : 'bar' } },
                { id : 3, address : { city : 'baz' } }
            ]
        });

    store.filter('city', 'baz');

Post Reply