Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unexpected expansion of nodes when using search highlighting feature #7183

Closed
marciogurka opened this issue Jul 18, 2023 · 0 comments
Closed
Assignees
Labels
bug Something isn't working example forum Issues from forum OEM OEM customer premium resolved Fixed but not yet released (available in the nightly builds)
Milestone

Comments

@marciogurka
Copy link

Forum post

"Hello,

I'm using a tree grid in combination with Grid.feature.Search.

When I collapse all of the nodes and then expand individual ones, all of the nodes are being unexpectedly expanded.

Replication steps:

  • Paste the attached code into the Tree Grid demo.
  • Collapse the "Gates 1 - 5" and "Gates 6 - 10" nodes.
  • When expanding either one of these nodes, notice that it expands both of them, instead of just the one that I clicked"
import { StringHelper, TreeGrid, GridRowModel } from '../../build/grid.module.js?469229';
import shared from '../_shared/shared.module.js?469229';

class Gate extends GridRowModel {
    static get fields() {
        return [
            {
                name : 'capacity',
                type : 'number'
            },
            'domestic',
            'airline',
            'manager'
        ];
    }
}

class Terminal extends GridRowModel {
    static fields = [
        'lounges',
        'concourses'
    ];
}

// Transform a parent node to a leaf node when all its children are removed
Gate.convertEmptyParentToLeaf = true;

const tree = new TreeGrid({

appendTo : 'container',

features : {
    cellEdit   : true,
    filter     : true,
    rowReorder : true,
    stripe     : true,
search: true
    },

loadMask : 'Loading tree data...',

columns : [
    { text : 'Id', field : 'id', width : 40, editor : false },
    { text : 'ParentIndex', field : 'parentIndex', width : 40, hidden : true },
    {
        text        : 'Name',
        field       : 'name',
        flex        : 3,
        type        : 'tree',
        touchConfig : { editor : false },
        htmlEncode  : false,
        renderer({ value, record, row }) {
            if (record instanceof Terminal) {
                row.addCls('terminal');
                return `${StringHelper.encodeHtml(value)}<div class="lounge-list">
                    <div>Lounges</div>
                    <ul>
                        ${record.lounges?.map(name => `<li>
                            <i class="b-fa b-fa-martini-glass"></i>${StringHelper.encodeHtml(name)}
                        </li>`).join('')}
                    </ul>
                </div>`;
            }

            // Have to wrap in a div to not get assigned as a text-node, which would render O`Hare as `O&39;Hare`
            return `<div>${StringHelper.encodeHtml(value)}</div>`;
        }
        // You can customize expand/collapse icons
        // expandIconCls   : 'b-fa b-fa-plus-square',
        // collapseIconCls : 'b-fa b-fa-minus-square'
    },
    { type : 'aggregate', text : 'Capacity', field : 'capacity', flex : 1 },
    { text : 'Domestic', field : 'domestic', flex : 1 },
    { text : 'Airline', field : 'airline', flex : 1 },
    { text : 'Responsible<br/>Manager', field : 'manager', width : 100, htmlEncodeHeaderText : false }
],

store : {
    modelClass : Gate,
    readUrl    : 'data/kastrup-airport.json',
    autoLoad   : true,
    // The default model is a Gate (see above) and in this createRecord method below, we can decide at runtime based
    // on the data which model class to use. This is useful when your record types aren't homogenous.
    createRecord(data) {
        let modelClass = this.modelClass;
        if (data.type === 'terminal') {
            modelClass = Terminal;
        }
        return new modelClass(data, this);
    }
},

tbar : [
    {
        type        : 'button',
        ref         : 'customButton',
        icon        : 'b-fa-folder-open',
        pressedIcon : 'b-fa-plane',
        text        : 'Use custom tree icons',
        toggleable  : true,
        onToggle({ pressed }) {
            tree.store.readUrl = 'data/' + (pressed ? 'ohare-airport.json' : 'kastrup-airport.json');
            tree.element.classList[pressed ? 'add' : 'remove']('ohare-airport');
            tree.store.load();
        }
    },
    {
        type     : 'button',
        ref      : 'expandAllButton',
        icon     : 'b-fa-angle-double-down',
        text     : 'Expand all',
        onAction : () => tree.expandAll()
    },
    {
        type     : 'button',
        ref      : 'collapseAllButton',
        icon     : 'b-fa-angle-double-up',
        text     : 'Collapse all',
        onAction : () => tree.collapseAll()
    },
    '->',
    {
        ref     : 'selectionModeButton',
        text    : 'Selection configuration',
        tooltip : 'Configure tree-related selectionMode settings',
        icon    : 'b-fa-cog',
        menu    : {
            items : [{
                text    : 'includeChildren',
                checked : false,
                tooltip : 'Activate to select all descendants when their parent gets selected',
                onToggle({ checked }) {
                    tree.selectionMode.includeChildren = checked;
                }

            }, {
                text    : 'includeParents = all',
                ref     : 'parentsAll',
                checked : false,
                tooltip : 'Activate to select parent when all its descendants gets selected',
                onToggle({ menu, checked }) {
                    if (!menu._isSettingChecked) {
                        tree.selectionMode.includeParents = checked;

                        if (checked) {
                            menu._isSettingChecked = true;
                            menu.widgetMap.parentsSome.checked = false;
                            delete menu._isSettingChecked;
                        }
                    }
                }
            }, {
                text    : 'includeParents = some',
                ref     : 'parentsSome',
                checked : false,
                tooltip : 'Activate to select parent when some of its descendants gets selected',
                onToggle({ menu, checked }) {
                    if (!menu._isSettingChecked) {
                        tree.selectionMode.includeParents = checked ? 'some' : false;
                        if (checked) {
                            menu._isSettingChecked = true;
                            menu.widgetMap.parentsAll.checked = false;
                            delete menu._isSettingChecked;
                        }
                    }
                }
            }]
        }

    }
]
});
tree.features.search.search('gate');
@marciogurka marciogurka added bug Something isn't working example premium forum Issues from forum OEM OEM customer labels Jul 18, 2023
@matsbryntse matsbryntse self-assigned this Feb 15, 2024
@matsbryntse matsbryntse added the ready for review Issue is fixed, the pull request is being reviewed label Feb 15, 2024
@matsbryntse matsbryntse added this to the 5.6.7 milestone Feb 15, 2024
@matsbryntse matsbryntse added resolved Fixed but not yet released (available in the nightly builds) and removed ready for review Issue is fixed, the pull request is being reviewed labels Feb 15, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working example forum Issues from forum OEM OEM customer premium resolved Fixed but not yet released (available in the nightly builds)
Projects
None yet
Development

No branches or pull requests

2 participants