Search code examples
htmlhtml-tablebootstrap-4bootstrap-table

Order html table on hidden values


I have a html table which uses the bootstrap table library to sort the data by column values. This works fine if the data is expressed as a float or int, but I have a column of times. I wish to have the times represented by a string in the form % hr & % min, however because they are a string they are not data-sortable. In the example below '15 hours and 2 minutes' is much larger than '32 minutes', however the sort will place '32 minutes' at the top as it begins with a 3.

Is there a way to have the table display my human readable values, while sorting on a different set of hidden data (total minutes)?

To be clear, the table must be interactable, so that the user can choose which columns the data is sorted by.

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css">
<link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/bootstrap-table/1.11.1/bootstrap-table.min.css">
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/bootstrap-table/1.11.1/bootstrap-table.min.js"></script>

<table id="table"
       class="table-striped"
       data-toggle="table"
       data-sort-name="traveltime"
       data-sort-order="desc">
    <thead>
        <tr>
            <th data-sortable="true">Name</th>
            <th data-sortable="true">Distance</th>
            <th data-field="traveltime" data-sortable="true">Travel Time</th>
            <th data-sortable="true">Created Date</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>Example Name</td>
            <td>15.1</td>
            <td>15 hr & 2 min</td>
            <td>2018-02-11 18:15:15</td>
        </tr>
        <tr>
            <td>Example Name 2</td>
            <td>10.1</td>
            <td>32 min</td>
            <td>2018-02-11 18:19:05</td>
        </tr>
    </tbody>
</table>

Let me know if I need to provide more information.


Solution

  • OK, as per my comment here is an answer based upon the table data as JavaScript (it could equally be a JSON API return).

    The table is as per your example with data fields defined in the <thead> but:

    1. Utilising a Bootstrap Table JavaScript initialisation to inject the table data from an array.
    2. Defining a formatter and sorter function for the travel time field.
    3. For convenience, I've used the momentjs library to deal with dates and durations.

    var data = [{
      name: 'Example Name',
      distance: 15.1,
      travelTime: 15 * 60 + 2, // '15 hr & 2 min',
      created: moment('2018-02-11 18:15:15').toDate(),
    }, {
      name: 'Example Name 3',
      distance: 25.1,
      travelTime: 24 * 60 + 2, // '15 hr & 2 min',
      created: moment('2018-02-11 18:25:15').toDate(),
    }, {
      name: 'Example Name 2',
      distance: 10.1,
      travelTime: 32, // '32 min',
      created: moment('2018-02-11 18:19:05').toDate(),
    }]
    
    function formatTravelTime(value, row, index, field) {
      return moment.duration(value, 'minutes').humanize()
    }
    
    // this is not required in the case, but as an example of a sorter
    function travelTimeSorter(a, b) {
    	return a < b ? -1 : (a > b ? 1 : 0)
    }
    
    $(function() {
      $('#table').bootstrapTable({
        data: data
      });
    });
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.20.1/moment.js"></script>
    <script src="https://rawgit.com/wenzhixin/bootstrap-table/master/src/bootstrap-table.js"></script>
    <link href="https://rawgit.com/wenzhixin/bootstrap-table/master/src/bootstrap-table.css" rel="stylesheet"/>
    
    <table id="table">
      <thead>
        <tr>
          <th data-field="name" data-sortable="true">Name</th>
          <th data-field="distance" data-sortable="true">Distance</th>
          <th data-field="travelTime" data-formatter="formatTravelTime" data-sorter="travelTimeSorter" data-sortable="true">Travel Time</th>
          <th data-field="created" data-sortable="true">Created Date</th>
        </tr>
      </thead>
    </table>