Our blazing fast Grid component built with pure JavaScript


Post by ogardnerffdc »

Hello,

I have a lazy loaded tree grid where I'm setting the children property of records to true to indicate that data will be loaded at a later point. These records are loaded by overriding the loadChildren function in the store.

Along with the tree grid, I have implemented a searching UI to allow users to search the tree grid for records. Upon searching, I would like to use the https://www.bryntum.com/products/scheduler/docs/api/Grid/feature/Search API to highlight the results. However, when I do this, the search API throws an error:

Screenshot 2023-05-31 at 11.24.14.png
Screenshot 2023-05-31 at 11.24.14.png (867.83 KiB) Viewed 147 times

I have managed to reproduce this in the Bryntum demos using the following code:

import { TreeGrid, DomHelper, DateHelper, ObjectHelper, DataGenerator } from '../../build/grid.module.js?468078';
import shared from '../_shared/shared.module.js?468078';

class App {
    constructor() {
        const me = this;

    me.grid = new TreeGrid({

        appendTo : 'container',

        features : {
            search : true
        },
        columns : [
            { text : 'Name', field : 'name', type: 'tree' },
        ],
        data : [{
        id: 'id1',
        expanded: true,
        name: 'Parent 1',
        children: [
            {
                id: 'id2',
                name: 'Child 1'
            }
        ]
    },
    {
        id: 'id3',
        expanded: true,
        name: 'Parent 2',
        children: [
            {
                id: 'id4',
                name: 'Child 2'
            }
        ]
    },
    {
        id: 'id5',
        expanded: false,
        name: 'Parent 3',
        children: true
    }
],

        tbar : [
            {
                type      : 'text',
                ref       : 'searchField',
                clearable : true,
                label     : '<i class="b-icon b-icon-search"></i>',
                listeners : {
                    change  : 'onSearchFieldChange',
                    clear   : 'onSearchFieldClear',
                    thisObj : me
                }
            },
            {
                type     : 'button',
                ref      : 'prevBtn',
                icon     : 'b-icon-up',
                disabled : true,
                tooltip  : {
                    html : `
                        <div class="header">Go to previous hit</div>
                        <div class="content">
                            You can also hold <code>[shift]</code> and press <code>[f3]</code> or <code>[ctrl]/[cmd] + [g]</code>
                        </div>
                    `,
                    position : 'bottom center'
                },
                listeners : {
                    action  : 'onPrevHit',
                    thisObj : me
                }
            },
            {
                type     : 'button',
                ref      : 'nextBtn',
                icon     : 'b-icon-down',
                disabled : true,
                tooltip  : {
                    html : `
                        <div class="header">Go to next hit</div>
                        <div class="content">
                            You can also press <code>[f3]</code> or <code>[ctrl]/[cmd] + [g]</code>
                        </div>
                    `,
                    position : 'bottom center'
                },
                listeners : {
                    action  : 'onNextHit',
                    thisObj : me
                }
            },
            '<code>F3</code> or <code>CTRL/CMD + G</code> navigates hits. Add <code>SHIFT</code> to go backwards'
        ],

        listeners : {
            search      : 'onSearchPerformed',
            clearsearch : 'onClearPerformed',
            thisObj     : me
        }
    });

    me.search = me.grid.widgetMap.searchField;
    me.previousBtn = me.grid.widgetMap.prevBtn;
    me.nextBtn = me.grid.widgetMap.nextBtn;
}

onNextHit() {
    this.grid.features.search.gotoNextHit(false, { animate : 300 });
}

onPrevHit() {
    this.grid.features.search.gotoPrevHit({ animate : 300 });
}

onSearchPerformed({ find, found }) {
    const
        me     = this,
        search = me.search;

    // Needed when you search by calling search method manually.
    // Suspend events so as not to cause feedback and do the search twice.
    if (!ObjectHelper.isEqual(search.value, find)) {
        search.suspendEvents();
        search.value = find instanceof Date ? DateHelper.format(find, 'L') : find;
        search.resumeEvents();
    }

    search.badge = found.length;
    DomHelper.focusWithoutScrolling(me.grid.element);
    me.previousBtn.enable();
    me.nextBtn.enable();
}

onClearPerformed() {
    const me = this;

    // need when you reset search by calling clear method manually
    me.search.value = '';

    me.search.badge = null;
    me.previousBtn.disable();
    me.nextBtn.disable();
}

onSearchFieldClear() {
    this.grid.features.search.clear();
}

onSearchFieldChange({ value }) {
    this.grid.features.search.search(value);
}
}

const app = window.app = new App();

setTimeout(() => app.grid.features.search.search('child'), 10);

Please could you confirm whether this is a bug or if I am using these features incorrectly.

Thank you!


Post by mats »

Reproduced, thanks for reporting. https://github.com/bryntum/support/issues/6896


Post Reply