jQuery problema con punto separador de miles en ordenación de números

publicado por: Anonymous

Dado el siguiente código jQuery para ordenar filas de una tabla, los números con punto para separar miles no se ordenan correctamente.

Los siguientes números :25.000, 1.000, 2.500, 4.000, 850,50, se ordenan como: 850,50, 25.000, 4.000, 2.500, 1.000.

Lo correcto sería que la ordenación final quedara cómo: 25.000, 4.000, 2.500, 1.000, 850,50.

Necesito poder ordenar los números del ejemplo sin eliminar el punto separador de miles y la coma que delimita decimales (ej: 850,50).

El código jQuery:

$('th').each(function (column) {
    $(this).addClass('sortable').click(function () {
        var findSortKey = function ($cell) {
            return $cell.find('.sort-key').text().toUpperCase()+ ' ' + $cell.text().toUpperCase();

        };
        var sortDirection = $(this).is('.sorted-asc') ? -1 : 1;
        var $rows = $(this).parent().parent().parent().find('tbody tr').get();
        var bob = 0;
        // Loop thorugh all records and find
        $.each($rows, function (index, row) {
            row.sortKey = findSortKey($(row).children('td').eq(column));
        });

        // Compare and sort the rows alphabetically or numerically
        $rows.sort(function (a, b) {
            if (a.sortKey.indexOf('-') == -1 && (!isNaN(a.sortKey) && !isNaN(a.sortKey))) {
                 // Rough Numeracy check

                    if (parseInt(a.sortKey) < parseInt(b.sortKey)) {
                        return -sortDirection;
                    }
                    if (parseInt(a.sortKey) > parseInt(b.sortKey)) {
                        return sortDirection;
                    }

            } else {
                if (a.sortKey < b.sortKey) {
                    return -sortDirection;
                }
                if (a.sortKey > b.sortKey) {
                    return sortDirection;
                }
            }
            return 0;
        });

        // Add the rows in the correct order to the bottom of the table
        $.each($rows, function (index, row) {
            $('tbody').append(row);
            row.sortKey = null;
        });

        // Identify the collumn sort order
        $('th').removeClass('sorted-asc sorted-desc');
        var $sortHead = $('th').filter(':nth-child(' + (column + 1) + ')');
        sortDirection == 1 ? $sortHead.addClass('sorted-asc') : $sortHead.addClass('sorted-desc');

        // Identify the collum to be sorted by
        $('td').removeClass('sorted').filter(':nth-child(' + (column + 1) + ')').addClass('sorted');
    });
});

Gracias de antemano!

solución

Una modificación simple seria:

Remover el separador de miles (.) y reemplazar el separador decimal (,) antes de hacer la comparación numérica.

Nota: Para indicar el tipo de orden a aplicarse, he agregado un data attribute (eg: data-sort-type="numeric") solo en la columna que deseo ordenar de forma numérica.

Entonces, podría quedar algo así:

_x000D_

_x000D_

// Objeto global de configuración numérica_x000D_
var globalNumberConfig = {_x000D_
  decimalSeparator: ',',_x000D_
  thousandSeparator: '.'_x000D_
};_x000D_
_x000D_
$('th').each(function (column) {_x000D_
    $(this).addClass('sortable').click(function () {_x000D_
        var findSortKey = function ($cell) {_x000D_
            return $cell.find('.sort-key').text().toUpperCase()+ ' ' + $cell.text().toUpperCase();_x000D_
_x000D_
        };_x000D_
        var $columnCell = $(this);_x000D_
        var sortDirection = $columnCell.is('.sorted-asc') ? -1 : 1;_x000D_
        var $rows = $columnCell.closest('table').find('tbody tr').get();_x000D_
        var bob = 0;_x000D_
        //------------------------_x000D_
        // CHANGES HERE!_x000D_
        var thousandSepRE = new RegExp('\'+globalNumberConfig.thousandSeparator, 'g');_x000D_
        var decimalSep = globalNumberConfig.decimalSeparator;_x000D_
        var sortType = $columnCell.data('sortType') || 'text';_x000D_
        //------------------------_x000D_
_x000D_
        // Loop thorugh all records and find_x000D_
        $.each($rows, function (index, row) {_x000D_
            row.sortKey = findSortKey($(row).children('td').eq(column));_x000D_
        });_x000D_
_x000D_
        // Compare and sort the rows alphabetically or numerically_x000D_
        $rows.sort(function (a, b) {_x000D_
            if (sortType === 'numeric' ) {_x000D_
                    //------------------------_x000D_
                    // CHANGES HERE!_x000D_
                    // Get acutal numerical value by repalcing thousand and decimal separators_x000D_
                    var aValue = parseFloat(a.sortKey.replace(thousandSepRE, '').replace(decimalSep, '.')) || 0;_x000D_
                    var bValue = parseFloat(b.sortKey.replace(thousandSepRE, '').replace(decimalSep, '.')) || 0;_x000D_
_x000D_
                    // Rough Numeracy check_x000D_
                    if (aValue < bValue) {_x000D_
                        return -sortDirection;_x000D_
                    }_x000D_
                    if (aValue > bValue) {_x000D_
                        return sortDirection;_x000D_
                    }_x000D_
                    //------------------------_x000D_
_x000D_
            } else {_x000D_
                if (a.sortKey < b.sortKey) {_x000D_
                    return -sortDirection;_x000D_
                }_x000D_
                if (a.sortKey > b.sortKey) {_x000D_
                    return sortDirection;_x000D_
                }_x000D_
            }_x000D_
            return 0;_x000D_
        });_x000D_
_x000D_
        // Add the rows in the correct order to the bottom of the table_x000D_
        $.each($rows, function (index, row) {_x000D_
            $('tbody').append(row);_x000D_
            row.sortKey = null;_x000D_
        });_x000D_
_x000D_
        // Identify the collumn sort order_x000D_
        $('th').removeClass('sorted-asc sorted-desc');_x000D_
        var $sortHead = $('th').filter(':nth-child(' + (column + 1) + ')');_x000D_
        sortDirection == 1 ? $sortHead.addClass('sorted-asc') : $sortHead.addClass('sorted-desc');_x000D_
_x000D_
        // Identify the collum to be sorted by_x000D_
        $('td').removeClass('sorted').filter(':nth-child(' + (column + 1) + ')').addClass('sorted');_x000D_
    });_x000D_
});

_x000D_

<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">_x000D_
<table class="table">_x000D_
    <caption>Optional table caption.</caption>_x000D_
    <thead>_x000D_
        <tr>_x000D_
            <th>#</th>_x000D_
            <th data-sort-type="numeric">$</th>_x000D_
        </tr>_x000D_
    </thead>_x000D_
    <tbody>_x000D_
        <tr>_x000D_
            <td scope="row">A</td>_x000D_
            <td>0 €</td>_x000D_
        </tr>_x000D_
        <tr>_x000D_
            <td scope="row">B</td>_x000D_
            <td>-5.025 €</td>_x000D_
        </tr>_x000D_
        <tr>_x000D_
            <td scope="row">C</td>_x000D_
            <td>11.789 €</td>_x000D_
        </tr>_x000D_
        <tr>_x000D_
            <td scope="row">D</td>_x000D_
            <td>7.766 €</td>_x000D_
        </tr>_x000D_
        <tr>_x000D_
            <td scope="row">E</td>_x000D_
            <td>5.295 €</td>_x000D_
        </tr>_x000D_
        <tr>_x000D_
            <td scope="row">F</td>_x000D_
            <td>14.861 €</td>_x000D_
        </tr>_x000D_
    </tbody>_x000D_
</table>_x000D_
_x000D_
<script type="text/javascript" src="https://code.jquery.com/jquery-1.12.4.min.js"></script>

_x000D_

_x000D_

_x000D_

Respondido por: Anonymous

Leave a Reply

Your email address will not be published. Required fields are marked *