Sorting a table with two header lines

My table structure looks like this:

enter image description here

This is my HTML:

<table id="jackpotwatch" style="width:700px;">
        <thead>
          <tr>

              <th>Location</th>
              <th colspan="2">Full Name</th>
              <th>Amount</th>

          </tr>
          <tr >
            <th>Asset</th>
            <th>Patron ID</th>
            <th>User</th>
            <th>Date/Time</th>
          </tr>
        </thead>
        <tbody>
           <tr>
              <td>Salem</td>
              <td colspan="2">Bob galvin</td>
              <td>$3400</td>
           </tr>
           <tr>
             <td>assert1</td>
             <td>1148</td>
             <td>sjauser</td>
             <td>11/12 10:39 AM</td>
           </tr>
           <tr>
              <td>chennai</td>
              <td colspan="2">sally n safer</td>
              <td>$400</td>
           </tr>
           <tr>
             <td>sdfsdgt1</td>
             <td>4747</td>
             <td>sjauser</td>
             <td>11/12 10:39 AM</td>
           </tr>
           <tr>
              <td>Mazdgfdg</td>
              <td colspan="2">afdagadg</td>
              <td>789769</td>
           </tr>
           <tr>
             <td>qwqeqe</td>
             <td>47467</td>
             <td>sjauser</td>
             <td>11/12 10:39 AM</td>
           </tr>
           <tr>
              <td>hurtyry</td>
              <td colspan="2">afadfadg</td>
              <td>$12000</td>
           </tr>
           <tr>
             <td>afadsf</td>
             <td>25426546</td>
             <td>sjauser</td>
             <td>11/12 10:39 AM</td>
           </tr>
        </tbody>
        </table>

      

When I click on the Amount heading, the sorting amounts ($ 3400, $ 400, $ 12000) should be sorted, etc. Likewise, the Date / Time field must also be sorted based on value.

I used the Tablesorter plugin, but this plugin did not sort all the columns. It is not sorting the last column and the second row header in this table. I also used the Tinysort plugin, but it changes the table structure during sorting.

I cannot change the structure of the table, as this is the biggest requirement of our client. Please provide some guidance on this sorting issue which is very helpful to me.

Any custom sorting that we can apply suggests how I can do this.

+3


source to share


2 answers


Presumably, you want the two lines for each entry to remain grouped together, in which case the Tablesorter is not designed to do what you want. Tinysort might work, though, if you were willing to put each pair of lines on your own tbody

:

<table id="jackpotwatch" style="width:700px">
    <thead>
      <tr>
          <th>Location</th>
          <th colspan="2">Full Name</th>
          <th>Amount</th>
      </tr>
      <tr >
        <th>Asset</th>
        <th>Patron ID</th>
        <th>User</th>
        <th>Date/Time</th>
      </tr>
    </thead>
    <tbody>
       <tr>
          <td>Salem</td>
          <td colspan="2">Bob galvin</td>
          <td>$3400</td>
       </tr>
       <tr>
         <td>assert1</td>
         <td>1148</td>
         <td>sjauser</td>
         <td>11/12 10:39 AM</td>
       </tr>
    </tbody>
    <tbody>
       <tr>
          <td>chennai</td>
          <td colspan="2">sally n safer</td>
          <td>$400</td>
       </tr>
       <tr>
         <td>sdfsdgt1</td>
         <td>4747</td>
         <td>sjauser</td>
         <td>11/12 10:39 AM</td>
       </tr>
    </tbody>
    ...
</table>

      

Since Tinysort can apparently sort by any element, you must tell it to sort the elements tbody

instead of strings. Your script could do something like this, loosely based on the table example in the Tinysort docs:



$(document).ready(function() {
    var aAsc = [];
    $("#jackpotwatch>thead th").each(function(nr) {
        $(this).click(function() {
            aAsc[nr] = aAsc[nr] == 'asc' ? 'desc' : 'asc';
            $("#jackpotwatch>tbody").tsort('td:eq(' + nr + ')', {order: aAsc[nr]});
        });
    });
});

      

It depends on the fact that the header lines have exactly the same number of cells as the lines of each tbody.

+1


source


See Demo here.

I don't have a plugin for you, but for your specific situation, I came up with the following approach:

/**
 * This approach assumes that records are always comprised of 2 rows. It is possible to make this configurable.
 */
;(function() {
  //Get the table
    var table = $("#jackpotwatch");

    //Make head header in the THEAD sortable.
    $("thead th", table).on("click", onSortableClicked);

    //Handle the sortable clicked event.
    function onSortableClicked(e) {
        //Find the column position.
        var c = -1, child = e.target;
        while ((child = child.previousSibling) != null)
            if (child.nodeType == 3) ++c;

        //Find the row position.
        var r = -1, child = e.target.parentNode;
        while ((child = child.previousSibling) != null)
            if (child.nodeType == 3) ++r;


        var subject = $("tbody", table);

        var replacement = sort(subject, r, c);

        subject.replaceWith(replacement);
    }

    function sort(subject, r, c) {
        var rows = $("tr", subject); //Get all the rows from the tbody.
        var sorted = document.createElement("tbody");

        var vals = [];
        for (var i = 0; i < rows.length; i+=2) {
            var record = [rows.get(i), rows.get(i+1)]; //Record is two rows.
            var sub = record[r].children[c].innerText; //This is our sort subject.

            vals.push({"sub": sub, "record": record});
        }

        vals.sort(compare);

        for (var i = 0; i < vals.length; ++i) {
            var val = vals[i];
            sorted.appendChild(val.record[0]);
            sorted.appendChild(val.record[1]);
        }

        return sorted;
    }

    function compare(a, b) {
        var atext = a.sub.toLowerCase();
        var btext = b.sub.toLowerCase();
        return atext < btext ? -1 : atext > btext ? 1 : 0;
    }
})();

      

This makes every item TH

in an item THEAD

sortable. It sorts it based on text, bottom, comparison.

It is hard-coded only to work with records that are 2 sets of rows, but can be extended to allow configuration of how many rows are in one record, or even output this automatically by counting how many rows are in THEAD

.



I used this in the following HTML:

<table id="jackpotwatch">
    <thead>
        <tr>
            <th>Location</th>
            <th colspan="2">Full Name</th>
            <th>Amount</th>
        </tr>
        <tr>
            <th>Asset</th>
            <th>Patron ID</th>
            <th>User</th>
            <th>Date/Time</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>Salem</td>
            <td colspan="2">Bob galvin</td>
            <td>$3400</td>
        </tr>
        <tr>
            <td>assert1</td>
            <td>1148</td>
            <td>sjauser</td>
            <td>11/12 10:39 AM</td>
        </tr>
        <tr>
            <td>chennai</td>
            <td colspan="2">sally n safer</td>
            <td>$400</td>
        </tr>
        <tr>
            <td>sdfsdgt1</td>
            <td>4747</td>
            <td>sjauser</td>
            <td>11/12 10:39 AM</td>
        </tr>
        <tr>
            <td>Mazdgfdg</td>
            <td colspan="2">afdagadg</td>
            <td>789769</td>
        </tr>
        <tr>
            <td>qwqeqe</td>
            <td>47467</td>
            <td>sjauser</td>
            <td>11/12 10:39 AM</td>
        </tr>
        <tr>
            <td>hurtyry</td>
            <td colspan="2">afadfadg</td>
            <td>$12000</td>
        </tr>
        <tr>
            <td>afadsf</td>
            <td>25426546</td>
            <td>sjauser</td>
            <td>11/12 10:39 AM</td>
        </tr>
    </tbody>
</table>

      

Make sure to place the script either after the HTML or in the prepared event handler:

$(document).ready(function() {
    //Sorting code from above goes here.
});

      

+1


source







All Articles