jQWidgets Forums

jQuery UI Widgets Forums Grid Custom sort with column defined in dataAdapter.beforeLoadComplete

This topic contains 2 replies, has 2 voices, and was last updated by  aurelien.clergeot@elca.ch 8 months, 2 weeks ago.

Viewing 3 posts - 1 through 3 (of 3 total)
  • Author
  • In the following example, I implemented custom sort as showed in the demo https://www.jqwidgets.com/jquery-widgets-demo/demos/jqxgrid/customsorting.htm?ui-start.

    It works fine for the Id (sorted numerically even though the column type is defined as a string).
    But the sort by FullName gets broken : the compare function cannot read FullName because it is not in the data passed to the source, but it gets added afterwards in the dataAdapter.

    There has to be a way to make it work, because the default sort works just fine, but I don’t see how I could make it work.
    Thanks for your help

    let data = [
        { Id: 1, firstName: 'John', lastName: 'Doe' },
        { Id: 2, firstName: 'Jane', lastName: 'Dae' },
    ];
    
    let sortColumn;
    let getFieldFn;
    function customSort(column, direction) {
        let sorted = [...data];
        sortColumn = (typeof column === "function") ? 'FUNCTION' : column;
    
        if (direction === 'ascending') direction = true;
        if (direction === 'descending') direction = false;
    
        const tmpToString = Object.prototype.toString;
        Object.prototype.toString = (typeof column == "function") ? column : function () { return this[column] };
        if (direction != null) {
            sorted.sort(compare);
            if (!direction) {
                sorted.reverse();
            }
        }
        source.localdata = sorted;
        $('#grid').jqxGrid('updatebounddata', 'sort');
        Object.prototype.toString = tmpToString;
    }
    function compareInner(a, b) {
        if (a < b) return -1;
        if (b < a) return 1;
        return 0;
    }
    function compare(value1, value2) {
        let v1;
        let v2;
        switch (sortColumn) {
        case 'Id': // custom sort works as expected for Id (sorted numerically instead of alphabetically)
            v1 = parseFloat(value1.Id);
            v2 = parseFloat(value2.Id);
            break;
        case 'FullName': // sort is broken for FullName
            // can't read value1.FullName (returns undefined), and String() ctor hack does not work either
        default:
            v1 = String(value1).toLowerCase();
            v2 = String(value2).toLowerCase();
            console.log(sortColumn, v1, v2);
            break;
        }
        return compareInner(v1, v2);
    }
    
    const source = {
        datatype: 'json',
        sort: customSort,
        localdata: data,
        id: 'Id',
        datafields: [
            { name: 'Id', type: 'string' }, /* type: 'number' does not work with filter type input */
            { name: 'FirstName', type: 'string' },
            { name: 'LastName', type: 'string' },
        ],
    };
    
    const dataAdapter = new $.jqx.dataAdapter(source, {
        beforeLoadComplete: (records) => {
            for (let rec of records) {
                rec.FullName = '${(rec?.LastName || '').toUpperCase()} ${(rec?.FirstName || '')}'.trim(); // backticks got broken by forum
            }
            return records;
        }
    });
    
    $('#grid').jqxGrid({
        width: '100%',
        height: '100%',
        autoheight: false,
        theme: 'energyblue',
        sortable: true,
        filterable: true,
        columns: [
            { text: 'Identifier', datafield: 'Id', width: '100px', filtertype: 'input' },
            { text: 'Full Name', datafield: 'FullName', width: '300px', filtertype: 'input' },
            { text: 'Last Name', datafield: 'LastName', width: '160px', filtertype: 'input' },
            { text: 'First Name', datafield: 'FirstName', width: '160px', filtertype: 'input' },
        ]
    });
    

    admin
    Keymaster

    Hi,

    The issue here is that you use let sorted = […data]; i.e the original data instead of the dataAdapter’s data. In the original data, FullName is not defined and this is the reason it returns an error. You can extend the ‘data’ array with the ‘FullName’ field before binding it through the dataAdapter and so it will have this field for sorting.

    Best regards,
    Peter Stoev

    jQWidgets Team
    https://www.jqwidgets.com/

    Indeed, I patched the data before assigning it to the adapter, and it works just fine now.
    Thanks for your help

Viewing 3 posts - 1 through 3 (of 3 total)

You must be logged in to reply to this topic.