Home > OS >  Extjs Sencha UUID custom sorting
Extjs Sencha UUID custom sorting

Time:09-27

I am trying to implement a custom sorting of the column UUID of my grid. I would like that the sorting reflects the sorting of the database by displaying the data for example in descending order, as follows:

select * from mytable order by uuid desc;

|    id    |                uuid              | 
|---------- ---------------------------------- 
| 10094875 |                                  | 
| 10093749 |                                  | 
| 10094905 |                                  |       
| 10094887 |                                  |                  
| 11268062 | fffffffffffffffffffff            |                 
| 11268010 | fffffffffffffffffffff            | 
| 11267357 | ffffffffffff                     | 
| 11267356 | fffff-fffff-ffff-ffff-ffff       | 
| 11267998 | eeda671280c7397c11347cb758e36b38 | 
| 10250739 | eeda671280c7397c11347cb758e36b38 |  

So in descending order, it should appear first the white spaces/empty item and after the UUID without the dashes, then the UUID with dashes.

At the moment these are my results when sorting descending:

enter image description here

It is close to what I want, but as you can see the empty rows are displayed at the bottom instead of the top. This is my code:

Ext.define('Traccar.model.MyModel', {
    extend: 'Ext.data.Model',
    identifier: 'negative',

    fields: [{
        ...
    }, {
    name: 'uuid',
    type: 'string',
    sortType: function (actualValue, replaceValue, arg1, arg2) {
          if (arg1 != null & arg2 != null) {
              if (actualValue === arg1 || actualValue === arg2) {
                  return replaceValue;
              } else
                  return actualValue;
          } else if (arg1 != null) {
              if (actualValue === arg1)
                  return replaceValue;
              else
                  return actualValue;
          } else
              return actualValue;
      }
}, ..
    }],   
});

Does anyone know how can I fix it?

CodePudding user response:

You can use a custom sorter function on the grid column uuid in order to get what you'd like. Since you want empty strings to appear first both in ASC and in DESC order, you need to define special rules. The sorter function receives two models (model1 and model2 for example) and should return -1 if model1 should be before model2, 0 if the order is the same, and 1 if model1 should be after model2. You also have to watch the direction property.

The function itself can look like this, it can be simplified, but shows all cases:

function (model1, model2) {
    const uuid1 = model1.get('uuid'),
        uuid2 = model2.get('uuid'),
        direction = this.getDirection();

    if (uuid1 == uuid2) { // same ordering
        return 0;
    }
    // if uuid1 is empty
    if (Ext.isEmpty(uuid1)) {
        return direction == 'ASC' ? -1 : 1;
    }
    // if uuid2 is empty
    if (Ext.isEmpty(uuid2)) {
        return direction == 'ASC' ? 1 : -1;
    }

    return uuid1 > uuid2 ? 1 : -1;
}

And this is the a complete example with local data, you can copy-paste it and run in a Sencha Fiddle:

Ext.define('MyModel', {
    extend: 'Ext.data.Model',
    fields: [{
        name: 'id',
        type: 'int'
    }, {
        name: 'uuid',
        type: 'string',
    }]
});

Ext.define('MyStore', {
    extend: 'Ext.data.Store',
    model: 'MyModel',
    data: [{
        id: 1,
        uuid: ''
    }, {
        id: 2,
        uuid: ''
    }, {
        id: 3,
        uuid: ''
    }, {
        id: 4,
        uuid: ''
    }, {
        id: 5,
        uuid: 'abc'
    }, {
        id: 6,
        uuid: 'def'
    }, {
        id: 7,
        uuid: 'ghi'
    }, {
        id: 9,
        uuid: 'jkl'
    }, {
        id: 9,
        uuid: 'mno'
    }, {
        id: 10,
        uuid: 'pqr'
    }],
    proxy: {
        type: 'memory'
    }
});

Ext.application({
    name: 'Fiddle',
    launch: function () {
        const store = Ext.create('MyStore');
        const grid = Ext.create({
            xtype: 'grid',
            renderTo: Ext.getBody(),
            store: store,
            title: 'Grid',
            columns: [{
                text: 'id',
                flex: 1,
                dataIndex: 'id'
            }, {
                text: 'uuid',
                flex: 4,
                dataIndex: 'uuid',
                sorter: function (model1, model2) {
                    const uuid1 = model1.get('uuid'),
                        uuid2 = model2.get('uuid'),
                        direction = this.getDirection();

                    if (uuid1 == uuid2) {
                        return 0;
                    }

                    if (Ext.isEmpty(uuid1)) {
                        return direction == 'ASC' ? -1 : 1;
                    }

                    if (Ext.isEmpty(uuid2)) {
                        return direction == 'ASC' ? 1 : -1;
                    }

                    return uuid1 > uuid2 ? 1 : -1;
                }
            }]
        });
    }
});

CodePudding user response:

There is no need to define sortType in the model, just the type of field string. In your store, simply add a sorter, like:

Ext.define('Traccar.store.MyStore', {
    model: 'negative',
    proxy: {...},
    sorters: [
        {
            property: 'uuid',
            direction: 'ASC'
        }
    ]
}

The grid should display the results as you expect them.

  • Related