Our blazing fast Grid component built with pure JavaScript


Post by MattSlalom »

I am wondering if there is a way via configs (enabling/disabling features) to hide basically all of the features below:

Screen Shot 2020-06-05 at 3.25.43 PM.png
Screen Shot 2020-06-05 at 3.25.43 PM.png (15.61 KiB) Viewed 2136 times

and only have the column hide/show options like shown in the columns sub menu as the main items:

Screen Shot 2020-06-05 at 3.25.59 PM.png
Screen Shot 2020-06-05 at 3.25.59 PM.png (6.66 KiB) Viewed 2136 times

I poked around in the docs and the only way I have found a way to get this was to create custom configs like so:

    contextMenu : {
        headerItems : [
            { columnCheckbox1 }, { columnCheckbox2},...
        ]
    }

I just wanted to make sure I wasn't overcomplicating this task.
Thanks for any help on the matter.


Post by pmiklashevich »

Hello,

Current implementation of ColumnPicker feature does not allow to set column items as the first level menu items, ignoring "Columns" parent menu item.

To get rid of other first level items, please disable corresponding features:

ColumnPicker feature adds "Hide column" first level menu item for columns which are hideable.

So first implementation might looks like this:

    features : {
        group       : false,
        sort        : false,
        contextMenu : {
            // if you don't need "Hide column" menu item
            processHeaderItems({ items }) {
                const hideColumnIndex = items.findIndex(item => item.name === 'hideColumn');

            if (hideColumnIndex > -1) {
                items.splice(hideColumnIndex, 1);
            }
        }
    }
},

But that will keep nesting items, you can see "Columns" as the first level item.

Снимок экрана 2020-06-08 в 13.29.46.png
Снимок экрана 2020-06-08 в 13.29.46.png (82.39 KiB) Viewed 2120 times

Here is an example of how you can implement your own menu items:

features : {
    group        : false,
    sort         : false,
    columnPicker : false,
    contextMenu  : {
        // implement your own column disabling
        processHeaderItems({ column, items }) {
            if (!(column instanceof TimeAxisColumn)) {
                const columns = scheduler.subGrids.locked.columns.query(column => column.hideable);

            items.push(...columns.map(column => {
                return {
                    text    : column.text,
                    name    : column.id,
                    checked : column.hidden !== true,
                    onToggle() {
                        column.hidden = !column.hidden;
                    }
                };
            }));
        }
    }
}
},
Снимок экрана 2020-06-08 в 13.52.37.png
Снимок экрана 2020-06-08 в 13.52.37.png (84.48 KiB) Viewed 2120 times

I've opened a feature request to make the ColumnPicker feature more configureable. https://github.com/bryntum/support/issues/894

Best regards,
Pavel

Pavlo Miklashevych
Sr. Frontend Developer


Post by pmiklashevich »

I see you're evaluating our Grid component, and my example is written for Scheduler, but the idea is the same. You can check how it works in Grid MultiRegion demo:

const grid = new Grid({
    adopt : 'container',

minHeight : '20em',

features : {
    group        : false,
    sort         : false,
    columnPicker : false,
    contextMenu  : {
        // implement your own column disabling
        processHeaderItems({ column, items }) {
            const columns = grid.subGrids[column.region].columns.query(column => column.hideable);
            // In case you need to show columns from all regions
            //const columns = grid.columns.query(column => column.hideable);

            items.push(...columns.map(column => {
                return {
                    text    : column.text,
                    name    : column.id,
                    checked : column.hidden !== true,
                    onToggle() {
                        column.hidden = !column.hidden;
                    }
                };
            }));
        }
    }
},

columns : [
    { text : 'First name', field : 'firstName', width : 180, region : 'left' },
    { text : 'Surname', field : 'surName', width : 180, region : 'left' },
    { text : 'Age', field : 'age', width : 180, region : 'middle' },
    { text : 'Score', field : 'score', width : 180, region : 'middle' },
    { text : 'Rank', field : 'rank', width : 180, region : 'middle' },
    { text : 'Percent', field : 'percent', width : 180, region : 'middle' },
    { text : 'Rating', field : 'rating', width : 180, region : 'middle' },
    { text : 'City', field : 'city', width : 180, region : 'right' },
    { text : 'Done', field : 'done', width : 180, region : 'right' }
].map(item => Object.assign(item, { draggable : false })), // configured all items as not draggable

If you don't need "Move column to ..." items, but want to keep columns draggable, you can simple remove those items in processHeaderItems handler.

Pavlo Miklashevych
Sr. Frontend Developer


Post by MattSlalom »

Awesome ,thank you for the super in depth answer! I got the column stuff working with your examples, however, I am running into another wall I believe. Is there anyway to keep the header functionality for sorting and dragging but keep it out of the contextMenu or is that also going to need some config finesse? Also, is it possible to lock columns to their respective section/subgraph/region while still maintaining dragging? Thanks again for any info.


Post by pmiklashevich »

Is there anyway to keep the header functionality for sorting and dragging but keep it out of the contextMenu or is that also going to need some config finesse?

There is no feature config to prevent adding to the header context menu. You can keep the feature enabled but simply find and remove sorting items from the "items" array in processHeaderItems.

Also, is it possible to lock columns to their respective section/subgraph/region while still maintaining dragging?

It's not supported by the ColumnReorder feature at the moment. I've opened a feature request: https://github.com/bryntum/support/issues/902
Meanwhile you can try to solve it on data level. Since Columns is a store it has beforeUpdate event. For example:

    columns : {
        data : [
            { text : 'First name', field : 'firstName', width : 180, region : 'left' }, .....
        ],
        listeners : {
            beforeUpdate({ record, changes }) {
                // constrain columns to their regions
                if (changes && changes.region && changes.region !== record.region) {
                    return false;
                }
            }
        }
    },

Pavlo Miklashevych
Sr. Frontend Developer


Post by MattSlalom »

Thanks for the super detailed responses btw, you've been super helpful. I just learned of some new requirements and I was having a bit of trouble regarding listeners. Sort is expected to happen on double click, I swore I thought I saw a listener around double click, and is there an easy way to invoke the columns defined sorter via an event listener rather than using native? I tried adding listeners under the column like so

columns: [
  {
    listeners:{}
  }
] 

But I couldn't get the events to trigger, is there an exhaustive list for all the column events? https://bryntum.com/docs/grid/#Grid/column/Column this suggests there are only 2

Secondly,
They want the contextMenu to only show up when you click the 3 dot icon on the right, is this in the realm of possibility? and if not is it possible to make it appear on single left click for only this header?

Screen Shot 2020-06-11 at 12.27.15 PM.png
Screen Shot 2020-06-11 at 12.27.15 PM.png (3.92 KiB) Viewed 2098 times

Third unrelated thing i'm seeing is when I scroll down on the page at all when I drag a column, the dragged column is floating (it looks like the header being dragged is locked in a specific Y coord, it's position seems relative to the height of the scroll. Is this a known bug or is something going on with my implementation?

Screen Shot 2020-06-11 at 12.29.51 PM.png
Screen Shot 2020-06-11 at 12.29.51 PM.png (7.8 KiB) Viewed 2098 times

Post by saki »

  1. The number of clicks on the column header to trigger the sorting is not currently configurable. You could write your own feature (extending the existing Sort feature) to sort on dblclick. What you might have seen in docs on dblclick is that it is the default trigger event for cell edit feature.
  2. Your listeners on columns are ignored because you pass them as item of the array when they're understood as data. If you want some listeners on https://bryntum.com/docs/grid/#Grid/data/ColumnStore you must pass them as:
        columns : {
            data : [
                { text : 'First name', field : 'firstName', width : 180, region : 'left' }, .....
            ],
            listeners : {
                beforeUpdate({ record, changes }) {
                    // constrain columns to their regions
                    if (changes && changes.region && changes.region !== record.region) {
                        return false;
                    }
                }
            }
        },
    Mind please that columns is a ColumnStore so it doesn't fire UI events.
  3. Yes https://bryntum.com/docs/grid/#Grid/column/Column fires only 2 public events. Raw clicks on the grid and its header are handled internally by grid features.
  4. 3-dot menu could be implemented using https://bryntum.com/docs/grid/#Grid/column/Column#config-headerRenderer If the menu would be too dynamic or complex, you could also do it by writing and registering a custom feature.
  5. I could not reproduce the odd dragging behavior. Can you reproduce it in one of our demos?

For the future: If you have multiple question it is better to create multiple posts in forum so that they can be taken one-by-one.


Post Reply