Table sorting with two rows of Header

2020-04-11 09:45发布

My Table structure is like below:

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" header the amount values ($3400, $400, $12000) should be sorted, etc. Like that Date/Time field also should sort based on the value.

I used Tablesorter plugin but that plugin not sorting all columns. It not sorting last column and second row header in this table. I also used Tinysort plugin but it change the table structure itself while sorting.

I cannot able to change the table structure as this is our client biggest requirement. Please provide some guide on this sorting problem which is very useful for me.

Any customized sorting we can apply means please suggest how can i do that.

2条回答
家丑人穷心不美
2楼-- · 2020-04-11 10:00

See the Demo here.

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

/**
 * 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 each TH element in the THEAD element, sortable. It sorts it based on a textual, lowercased, comparison.

It is hard coded to only work with records that are 2 row sets, but could be expanded to allow the configuration of how many rows make up a single record, or even deduce this automagically by counting how many rows are in the THEAD.

I used this on 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 a ready event handler:

$(document).ready(function() {
    //Sorting code from above goes here.
});
查看更多
贪生不怕死
3楼-- · 2020-04-11 10:20

Presumably you want the two rows for each entry to remain grouped together, in which case Tablesorter isn't designed to do what you want. Tinysort could work, though, if you were prepared to put each pair of rows into its 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 on any kind of element, you should be able to tell it to sort the tbody elements instead of the rows. 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]});
        });
    });
});

This relies on there being precisely the same number of cells in the header rows as in the rows of each tbody.

查看更多
登录 后发表回答