recorrer Clasificación de tabla HTML con JavaScript



recorrer tabla javascript (8)

Estoy buscando una solución de clasificación de tablas (en JavaScript) pero parece que aún no puedo encontrar una adecuada. Solo necesito ordenar cada columna alfabéticamente. No necesita ignorar ningún código ni ningún número ni trabajar con la moneda. Basta con hacer clic en el encabezado de la columna para cambiarla de z / za clasificada.

¿Alguien sabe de una solución realmente simple como esta?


Answer #1

La mejor manera que conozco para ordenar la tabla HTML con javascript es con la siguiente función.

Simplemente, transmita la identificación de la tabla que desea ordenar y el número de columna en la fila. asume que la columna que está ordenando es numérica o tiene números y hará regex replace para obtener el número en sí (ideal para monedas y otros números con símbolos).

function sortTable(table_id, sortColumn){
    var tableData = document.getElementById(table_id).getElementsByTagName('tbody').item(0);
    var rowData = tableData.getElementsByTagName('tr');            
    for(var i = 0; i < rowData.length - 1; i++){
        for(var j = 0; j < rowData.length - (i + 1); j++){
            if(Number(rowData.item(j).getElementsByTagName('td').item(sortColumn).innerHTML.replace(/[^0-9\.]+/g, "")) < Number(rowData.item(j+1).getElementsByTagName('td').item(sortColumn).innerHTML.replace(/[^0-9\.]+/g, ""))){
                tableData.insertBefore(rowData.item(j+1),rowData.item(j));
            }
        }
    }
}

Usando el ejemplo:

$(function(){
    // pass the id and the <td> place you want to sort by (td counts from 0)
    sortTable('table_id', 3);
});

Answer #2

Escribí un código que ordenará una tabla por una fila, asumiendo que solo hay un <tbody> y las celdas no tienen un colspan .

function sortTable(table, col, reverse) {
    var tb = table.tBodies[0], // use `<tbody>` to ignore `<thead>` and `<tfoot>` rows
        tr = Array.prototype.slice.call(tb.rows, 0), // put rows into array
        i;
    reverse = -((+reverse) || -1);
    tr = tr.sort(function (a, b) { // sort rows
        return reverse // `-1 *` if want opposite order
            * (a.cells[col].textContent.trim() // using `.textContent.trim()` for test
                .localeCompare(b.cells[col].textContent.trim())
               );
    });
    for(i = 0; i < tr.length; ++i) tb.appendChild(tr[i]); // append each row in order
}
// sortTable(tableNode, columId, false);

Si no desea hacer las suposiciones anteriores, deberá considerar cómo desea comportarse en cada circunstancia. (por ejemplo, poner todo en uno <tbody> o sumar todos los valores de colspan precedentes, etc.)

A continuación, puede adjuntar esto a cada una de sus tablas, por ejemplo, suponiendo que los títulos están en <thead>

function makeSortable(table) {
    var th = table.tHead, i;
    th && (th = th.rows[0]) && (th = th.cells);
    if (th) i = th.length;
    else return; // if no `<thead>` then do nothing
    while (--i >= 0) (function (i) {
        var dir = 1;
        th[i].addEventListener('click', function () {sortTable(table, i, (dir = 1 - dir))});
    }(i));
}

function makeAllSortable(parent) {
    parent = parent || document.body;
    var t = parent.getElementsByTagName('table'), i = t.length;
    while (--i >= 0) makeSortable(t[i]);
}

y luego invocar makeAllSortable onload .

Ejemplo de un fiddle trabajando en una mesa.


Answer #3

¡Solo volviendo a visitar una solución anterior , pensé en darle un lavado de cara para su aniversario ~ 5 años!

  • Javascript simple (ES6)
  • Hace la clasificación alfa y numérica - ascendente y descendente
  • Funciona en Chrome , Firefox , Safari (e IE11 , ver abajo)

Explicación rápida

  1. agregue un evento de click a todas las celdas de encabezado ( th ) ...
    1. para la table actual, encuentre todas las filas (excepto la primera) ...
    2. ordenar las filas, en función del valor de la columna cliqueada ...
    3. inserte las filas nuevamente en la tabla, en el nuevo orden.

const getCellValue = (tr, idx) => tr.children[idx].innerText || tr.children[idx].textContent;

const comparer = (idx, asc) => (a, b) => ((v1, v2) => 
    v1 !== '' && v2 !== '' && !isNaN(v1) && !isNaN(v2) ? v1 - v2 : v1.toString().localeCompare(v2)
    )(getCellValue(asc ? a : b, idx), getCellValue(asc ? b : a, idx));

// do the work...
document.querySelectorAll('th').forEach(th => th.addEventListener('click', (() => {
    const table = th.closest('table');
    Array.from(table.querySelectorAll('tr:nth-child(n+2)'))
        .sort(comparer(Array.from(th.parentNode.children).indexOf(th), this.asc = !this.asc))
        .forEach(tr => table.appendChild(tr) );
})));
table, th, td {
    border: 1px solid black;
}
th {
    cursor: pointer;
}
<table>
    <tr><th>Country</th><th>Date</th><th>Size</th><th>Cost</th></tr>
    <tr><td>France</td><td>2001-01-01</td><td><i>2,500</i></td><td>$1.23</td></tr>
    <tr><td><a href=#>spain</a></td><td><i>2005-05-05</i></td><td></td><td></td></tr>
    <tr><td><b>Lebanon</b></td><td><a href=#>2002-02-02</a></td><td><b>-17</b></td><td>$0.04</td></tr>
    <tr><td><i>Argentina</i></td><td>2005-04-04</td><td><a href=#>1,000</a></td><td>$3</td></tr>
    <tr><td>USA</td><td></td><td>-6</td><td>$1,238.00</td></tr>
</table>
<i><b>N.B.</b> Currencies are not yet parsed...</i>

Soporte IE11 (no ES6)

Si desea soportar IE11, necesitará deshacerse de la sintaxis de ES6 y agregar polyfills para Array.from , Array.forEach y Element.closest .

es decir

var getCellValue = function(tr, idx){ return tr.children[idx].innerText || tr.children[idx].textContent; }

var comparer = function(idx, asc) { return function(a, b) { return function(v1, v2) {
        return v1 !== '' && v2 !== '' && !isNaN(v1) && !isNaN(v2) ? v1 - v2 : v1.toString().localeCompare(v2);
    }(getCellValue(asc ? a : b, idx), getCellValue(asc ? b : a, idx));
}};

// do the work...
Array.from(document.querySelectorAll('th')).forEach(function(th) { th.addEventListener('click', function() {
        var table = th.closest('table');
        Array.from(table.querySelectorAll('tr:nth-child(n+2)'))
            .sort(comparer(Array.from(th.parentNode.children).indexOf(th), this.asc = !this.asc))
            .forEach(function(tr) { table.appendChild(tr) });
    })
});

Answer #4

Funciona mucho más que "simplemente ordenar", pero dataTables.net hace lo que necesita. Lo uso a diario y está bien soportado y MUY rápido (requiere jQuery)

http://datatables.net/

DataTables es un complemento para la biblioteca jQuery Javascript. Es una herramienta altamente flexible, basada en los fundamentos de la mejora progresiva, que agregará controles avanzados de interacción a cualquier tabla HTML.

Google Visualizations es otra opción, pero requiere un poco más de configuración que dataTables, pero NO requiere ningún framework / biblioteca particular (que no sea google.visualizations):

http://code.google.com/apis/ajax/playground/?type=visualization#table

Y hay otras opciones para ... especialmente si está usando uno de los otros frameworks JS. Dojo, Prototype, etc. tienen complementos de "mejora de la tabla" utilizables que proporcionan una funcionalidad mínima de clasificación de tablas. Muchos proporcionan más, pero lo reafirmaré ... Todavía me he topado con uno tan poderoso y tan rápido como datatables.net.


Answer #5

Podría tratar con una matriz json y la función sort . Es una estructura fácil de mantener manipulable (por ejemplo, clasificación).

No probado, pero esta es la idea. Eso respaldaría la ordenación múltiple y el orden secuencial si pasa una matriz en la que coloca las columnas en el orden en que deberían ordenarlas.

var DATA_TABLE = {
    {name: 'George', lastname: 'Blarr', age:45},
    {name: 'Bob', lastname: 'Arr', age: 20}
    //...
};

function sortDataTable(arrayColNames, asc) { // if not asc, desc
    for (var i=0;i<arrayColNames.length;i++) {
        var columnName = arrayColNames[i];
        DATA_TABLE = DATA_TABLE.sort(function(a,b){
            if (asc) {
                return (a[columnName] > b[columnName]) ? 1 : -1;
            } else {
                return (a[columnName] < b[columnName]) ? 1 : -1;
            }
        });
    }
}

function updateHTMLTable() {
    // update innerHTML / textContent according to DATA_TABLE
    // Note: textContent for firefox, innerHTML for others
}

Ahora imaginemos que necesita ordenar por apellido, luego nombre y finalmente por edad.

var orderAsc = true;
sortDataTable(['lastname', 'name', 'age'], orderAsc);

Debería dar como resultado algo como:

{name: 'Jack', lastname: 'Ahrl', age: 20},
{name: 'Jack', lastname: 'Ahrl', age: 22},
//...

Answer #6

Aquí hay un ejemplo completo usando JavaScript puro. El algoritmo utilizado para la clasificación es básicamente BubbleSort . Aquí hay un Fiddle .

   <!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8">

<script type="text/javascript">
    function sort(ascending, columnClassName, tableId) {
        var tbody = document.getElementById(tableId).getElementsByTagName(
                "tbody")[0];
        var rows = tbody.getElementsByTagName("tr");

        var unsorted = true;

        while (unsorted) {
            unsorted = false

            for (var r = 0; r < rows.length - 1; r++) {
                var row = rows[r];
                var nextRow = rows[r + 1];

                var value = row.getElementsByClassName(columnClassName)[0].innerHTML;
                var nextValue = nextRow.getElementsByClassName(columnClassName)[0].innerHTML;

                value = value.replace(',', '.'); // in case a comma is used in float number
                nextValue = nextValue.replace(',', '.');

                if (!isNaN(value)) {
                    value = parseFloat(value);
                    nextValue = parseFloat(nextValue);
                }

                if (ascending ? value > nextValue : value < nextValue) {
                    tbody.insertBefore(nextRow, row);
                    unsorted = true;
                }
            }
        }
    };
</script>
</head>
<body>
    <table id="content-table">
        <thead>
            <tr>
                <th class="id">ID <a
                    href="javascript:sort(true, 'id', 'content-table');">asc</a> <a
                    href="javascript:sort(false, 'id', 'content-table');">des</a>
                </th>
                <th class="country">Country <a
                    href="javascript:sort(true, 'country', 'content-table');">asc</a> <a
                    href="javascript:sort(false, 'country', 'content-table');">des</a>
                </th>
                <th class="some-fact">Some fact <a
                    href="javascript:sort(true, 'some-fact', 'content-table');">asc</a>
                    <a href="javascript:sort(false, 'some-fact', 'content-table');">des</a>
                <th>
            </tr>
        </thead>
        <tbody>
            <tr>
                <td class="id">001</td>
                <td class="country">Germany</td>
                <td class="some-fact">16.405</td>
            </tr>
            <tr>
                <td class="id">002</td>
                <td class="country">France</td>
                <td class="some-fact">10.625</td>
            </tr>
            <tr>
                <td class="id">003</td>
                <td class="country">UK</td>
                <td class="some-fact">15.04</td>
            </tr>
            <tr>
                <td class="id">004</td>
                <td class="country">China</td>
                <td class="some-fact">13.536</td>
            </tr>
        </tbody>
    </table>
</body>
</html>

También puede consultar la fuente desde aquí: https://github.com/wmentzel/table-sort


Answer #7

Otro enfoque para ordenar la tabla HTML. (basado en W3.JS HTML Sort )

var collection = [{
  "Country": "France",
  "Date": "2001-01-01",
  "Size": "25",
}, {
  "Country": "spain",
  "Date": "2005-05-05",
  "Size": "",
}, {
  "Country": "Lebanon",
  "Date": "2002-02-02",
  "Size": "-17",
}, {
  "Country": "Argentina",
  "Date": "2005-04-04",
  "Size": "100",
}, {
  "Country": "USA",
  "Date": "",
  "Size": "-6",
}]

for (var j = 0; j < 3; j++) {
  $("#myTable th:eq(" + j + ")").addClass("control-label clickable");
  $("#myTable th:eq(" + j + ")").attr('onClick', "w3.sortHTML('#myTable', '.item', 'td:nth-child(" + (j + 1) + ")')");
}

$tbody = $("#myTable").append('<tbody></tbody>');

for (var i = 0; i < collection.length; i++) {
  $tbody = $tbody.append('<tr class="item"><td>' + collection[i]["Country"] + '</td><td>' + collection[i]["Date"] + '</td><td>' + collection[i]["Size"] + '</td></tr>');
}
.control-label:after {
  content: "*";
  color: red;
}

.clickable {
  cursor: pointer;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://www.w3schools.com/lib/w3.js"></script>
<link href="https://www.w3schools.com/w3css/4/w3.css" rel="stylesheet" />
<p>Click the <strong>table headers</strong> to sort the table accordingly:</p>

<table id="myTable" class="w3-table-all">
  <thead>
    <tr>
      <th>Country</th>
      <th>Date</th>
      <th>Size</th>
    </tr>
  </thead>
</table>


Answer #8

Ordenar las filas de la tabla por celda. 1. Un poco más simple y tiene algunas características. 2. Distinga 'number' y 'string' al ordenar 3. Agregue alternar para ordenar por ASC, DESC

var index;      // cell index
var toggleBool; // sorting asc, desc 
function sorting(tbody, index){
    this.index = index;
    if(toggleBool){
        toggleBool = false;
    }else{
        toggleBool = true;
    }

    var datas= new Array();
    var tbodyLength = tbody.rows.length;
    for(var i=0; i<tbodyLength; i++){
        datas[i] = tbody.rows[i];
    }

    // sort by cell[index] 
    datas.sort(compareCells);
    for(var i=0; i<tbody.rows.length; i++){
        // rearrange table rows by sorted rows
        tbody.appendChild(datas[i]);
    }   
}

function compareCells(a,b) {
    var aVal = a.cells[index].innerText;
    var bVal = b.cells[index].innerText;

    aVal = aVal.replace(/\,/g, '');
    bVal = bVal.replace(/\,/g, '');

    if(toggleBool){
        var temp = aVal;
        aVal = bVal;
        bVal = temp;
    } 

    if(aVal.match(/^[0-9]+$/) && bVal.match(/^[0-9]+$/)){
        return parseFloat(aVal) - parseFloat(bVal);
    }
    else{
          if (aVal < bVal){
              return -1; 
          }else if (aVal > bVal){
                return 1; 
          }else{
              return 0;       
          }         
    }
}

debajo está la muestra html

            <table summary="Pioneer">

                <thead>
                    <tr>
                        <th scope="col"  onclick="sorting(tbody01, 0)">No.</th>
                        <th scope="col"  onclick="sorting(tbody01, 1)">Name</th>
                        <th scope="col"  onclick="sorting(tbody01, 2)">Belong</th>
                        <th scope="col"  onclick="sorting(tbody01, 3)">Current Networth</th>
                        <th scope="col"  onclick="sorting(tbody01, 4)">BirthDay</th>
                        <th scope="col"  onclick="sorting(tbody01, 5)">Just Number</th>
                    </tr>
                </thead>

                <tbody id="tbody01">
                    <tr>
                        <td>1</td>
                        <td>Gwanshic Yi</td>
                        <td>Gwanshic Home</td>
                        <td>120000</td>
                        <td>1982-03-20</td>
                        <td>124,124,523</td>
                    </tr>
                    <tr>
                        <td>2</td>
                        <td>Steve Jobs</td>
                        <td>Apple</td>
                        <td>19000000000</td>
                        <td>1955-02-24</td>
                        <td>194,523</td>
                    </tr>
                    <tr>
                        <td>3</td>
                        <td>Bill Gates</td>
                        <td>MicroSoft</td>
                        <td>84300000000</td>
                        <td>1955-10-28</td>
                        <td>1,524,124,523</td>
                    </tr>
                    <tr>
                        <td>4</td>
                        <td>Larry Page</td>
                        <td>Google</td>
                        <td>39100000000</td>
                        <td>1973-03-26</td>
                        <td>11,124,523</td>
                    </tr>
                </tbody>
            </table>





html-table