Premium support for our pure JavaScript UI components


Post by TeemuL »

Hi,

I am trying to implement custom sort operations on Grid. I am using external paging component and all the data adding and sorting will be done on outside the grid.

What I need is a sorting feature of data. The grid should not do the sorting on the current dataset it's store has, but still have the sorting indicators work like normal. So basically I want to prevent the sort actions happening on rows, but the sorting icons can stay.

I tried the following code, the listeners work and I can log the changes, but is there a way to prevent the sorting happening on the listener callback-methods? Also tried to replace the default sorter function in sorters array, but the method doesnt seem to work?

this.store = new Store({
    listeners: {
        beforeSort({ sorters }) {
            console.log('beforeSort', sorters); // This logs fine, can I prevent the sort here?
        },

    sort({ sorters }) {
        console.log('sorters', sorters); // or here?
    },
},
sorters: [
    {
        fn: (o1, o2) => {
            console.log('sorterFn'); // This doesn't log when sorting happens. Why?
            return 0;
        },
    },
],
});

Post by alex.l »

The public way to disable sorting on UI level is to set https://bryntum.com/docs/grid/#Grid/column/Column#config-sortable on false.
If you want to make your own logic instead of default, you could try to override https://bryntum.com/docs/grid/#Core/data/Store#function-sort method.

Another way that may be useful to check, is to use remote sorting. Please check here: https://bryntum.com/docs/grid/#Core/data/AjaxStore#remote-sorting

On your question why your sorters function was not called when sorting happens:
https://bryntum.com/docs/grid/#Core/data/Store#function-sort is replace sorters by default (see docs). This is the first reason. The second possible problem: you replaced sort method with your own, maybe that was the reason. Try to remove your override.

All the best,
Alex


Post by TeemuL »

The public way to disable sorting on UI level is to set Grid.column.Column#sortable on false.

This disables the whole functionality, since my sort listeners will stop working. So I don't really want to disable the whole sort feature, just the things that are happening with the rows.

If you want to make your own logic instead of default, you could try to override Core.data.Store#sort method.

Yes, this is what I was trying to do also but the override doesn't seem to work at all. I don't have any extra code besides this regarding the Store-object. The log never works and the columns do the default sorting.

this.store = new Store();

this.store.sort((recordA, recordB) => {
    console.log('custom sorting called');
    return 1;
});

Now if I try some other sort-method call with sorting parameters, I can programatically sort the columns.

Another way that may be useful to check, is to use remote sorting. Please check here: Core.data.AjaxStore#sorting

There is technical reasons I dont wan't to do this, connect the store to my backend. I need to handle the backend communication by myself in Angular.

On your question why your sorters function was not called when sorting happens:
Core.data.Store#sort is replace sorters by default (see docs). This is the first reason. The second possible problem: you replaced sort method with your own, maybe that was the reason. Try to remove your override.

Didn't quite catch the issues you mentioned, as I don't have any extra code that could replace the method somewhere, unless it can be replaced/overridden by some setting.

Now, theres the beforeSort-event that I can listen. Is there a way to stop the grid from doing the sorting in that listener method?


Post by alex.l »

According to an example in docs https://bryntum.com/docs/grid/#Core/data/mixin/StoreSort the correct format is:

// using custom sorting function
grid.store.sort({
    fn : (recordA, recordB) => {
        debugger
        // apply custom logic, for example:
        return recordA.name.length < recordB.name.length ? -1 : 1;
    }
});

I was able to catch debugger using our online example. Try to ran the code above in the console here: https://bryntum.com/examples/grid/basic/

Now, theres the beforeSort-event that I can listen. Is there a way to stop the grid from doing the sorting in that listener method?

No, this event is not preventable.

Please, let us know if it fixed your problem and unblocked you!

All the best,
Alex

All the best,
Alex


Post by TeemuL »

Didn't get that one to work on my project. But that's ok, I found another way to accomplish this:

this.store = new Store({
    listeners: {
        sort: ({ sorters }) => {
            this.store.removeAll();
            this.getNewSortedDataFromBackEndAndCallStoresAddMethod(sorters);
        },
    },
});

This does exactly what I wanted in first place. So the sorting indicator icon works properly on header click and the sorted data comes visible after delay (because the new data is fetched from backend). However theres still one issue. I had to call store-objects removeAll-method after the sort happens, because I don't want the current dataset to be sorted and shown as sorted as it is done by Grid. This leaves the user with empty grid for a while, untill the fresh data comes from the server. So my next question is: is there a way to add loader bar or some other loading indicator to replace/hide the rows so that user knows that the data is being refreshed?

Thanks for your help so far!


Post by alex.l »

Try this https://bryntum.com/docs/grid/#Core/widget/Mask

        Mask.mask({
            target : targetElement,
            text   : 'Masked (2 seconds)',
            mode   : 'dark-blur'
        });

    setTimeout(() => {
        Mask.unmask(targetElement);
    }, 2000);

All the best,
Alex


Post by TeemuL »

Yes, worked like a charm. I'm set for now. Thanks!


Post Reply