1

I have a table to be sorted. It has currently 3 columns:

currencyTd | accountNoTd | checkboxTd

I would like to sort it firstly by currency, then by checkbox (the checked ones to top) and lastly by account number. However, one modification is also needed - when initial loaded, the rows with a certain currency ("PLN") should be shown at the top of the table. Afterwards all remaining rows should be sorted as normally.

I use list.js to sort the rows. I have written the following sort function:

const options = {
        valueNames: ['currencyTd', 'accountNoTd', 'checkboxTd']
    };

    const accountsList = new List('accountsList', options);

    accountsList.sort('currencyTd', {
        order: 'asc',            
        sortFunction: function (a, b) {  
            if ((a.currencyTd === 'PLN') != (b.currencyTd === 'PLN')) {
                return a.currencyTd === 'PLN' ? 1 : -1;
            }
            return a.currencyTd > b.currencyTd ? 1 :
                   a.currencyTd < b.currencyTd ? -1 : 0;
        }

    });

But it's not working the way I expected. What may I do wrong?

EDIT: I forgot to add - the current function I write at this point (as in the code above) is supposed to sort it right just by the currency column. Whe I achieve it I want to add sorting by the other columns.

Hubert Kubiak
  • 511
  • 5
  • 23

1 Answers1

1

You could use a chained approach for all sort criteria.

var array = [
        { currencyTd: 'DEF', accountNoTd: 2, checkboxTd: 0 },
        { currencyTd: 'ABC', accountNoTd: 2, checkboxTd: 1 },
        { currencyTd: 'PLN', accountNoTd: 2, checkboxTd: 1 },
        { currencyTd: 'ABC', accountNoTd: 2, checkboxTd: 0 },
        { currencyTd: 'PLN', accountNoTd: 3, checkboxTd: 0 },
        { currencyTd: 'DEF', accountNoTd: 2, checkboxTd: 1 },
        { currencyTd: 'DEF', accountNoTd: 3, checkboxTd: 0 },
        { currencyTd: 'PLN', accountNoTd: 3, checkboxTd: 1 },
        { currencyTd: 'ABC', accountNoTd: 1, checkboxTd: 0 },
        { currencyTd: 'ABC', accountNoTd: 1, checkboxTd: 1 },
        { currencyTd: 'PLN', accountNoTd: 2, checkboxTd: 0 },
        { currencyTd: 'PLN', accountNoTd: 1, checkboxTd: 0 },
        { currencyTd: 'ABC', accountNoTd: 3, checkboxTd: 1 },
        { currencyTd: 'DEF', accountNoTd: 1, checkboxTd: 0 },
        { currencyTd: 'ABC', accountNoTd: 3, checkboxTd: 0 },
        { currencyTd: 'DEF', accountNoTd: 1, checkboxTd: 1 },
        { currencyTd: 'PLN', accountNoTd: 1, checkboxTd: 1 },
        { currencyTd: 'DEF', accountNoTd: 3, checkboxTd: 1 }
    ];

array.sort(function (a, b) {
    return (
        (a.currencyTd !== 'PLN') - (b.currencyTd !== 'PLN') || // sort PLN to top
        a.currencyTd.localeCompare(b.currencyTd) ||            // sort currencyTd ASC
        a.accountNoTd - b.accountNoTd ||                       // sort accountNoTd ASC
        a.checkboxTd - b.checkboxTd                            // sort checkboxTd ASC
    );
});
console.log(array);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Nina Scholz
  • 323,592
  • 20
  • 270
  • 324
  • That's very nice but is working just for the first column. The next lines after the 'or' operator is ignored. – Hubert Kubiak Jul 21 '17 at 11:10
  • where? above? i see the result sorted by `currencyTd` after `'PLN'` at top. – Nina Scholz Jul 21 '17 at 11:12
  • don't forget to wrap the parts after the return in parenthesis, or write it at one line, because of the [ASI](https://stackoverflow.com/questions/2846283/what-are-the-rules-for-javascripts-automatic-semicolon-insertion-asi). – Nina Scholz Jul 21 '17 at 11:19
  • I'm sorry, I just obtained value from my strings wrong. – Hubert Kubiak Jul 21 '17 at 11:42
  • sortFunction: function (a, b) { return ( b._values.currencyTd.indexOf('PLN') - a._values.currencyTd.indexOf('PLN') || a._values.currencyTd.localeCompare(b._values.currencyTd) || b._values.checkboxTd.indexOf('checked') - a._values.checkboxTd.indexOf('checked') || b._values.accountNoTd.replace(/\s/g, '') > a._values.accountNoTd.replace(/\s/g, '') ? -1 : 1 ); } – Hubert Kubiak Jul 21 '17 at 11:46
  • Thank you much :) – Hubert Kubiak Jul 21 '17 at 11:46
  • why do you need the replacement? – Nina Scholz Jul 21 '17 at 11:47
  • sortFunction: function (a, b) { return ( b._values.currencyTd.indexOf('PLN') - a._values.currencyTd.indexOf('PLN') || a._values.currencyTd.localeCompare(b._values.currencyTd) || b._values.checkboxTd.indexOf('checked') - a._values.checkboxTd.indexOf('checked') || b._values.accountNoTd < a._values.accountNoTd ); } – Hubert Kubiak Jul 21 '17 at 11:54
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/149803/discussion-between-nina-scholz-and-hub26). – Nina Scholz Jul 21 '17 at 11:57