0

I have some dynamic generated tables with these html structures

<table class="deliver">
  <tbody class="tbody">
    <tr id="10" data-position="10">
      <td>Title</td>
    </tr>
    <tr id="10" data-position="10">
      <td>Content</td>
    </tr>
    <tr id="23" data-position="23">
      <td>Title</td>
    </tr>
    <tr id="23" data-position="23">
      <td>Content</td>
    </tr>
  </tbody>
</table>

<table class="deliver">
  <tbody class="tbody">
    <tr id="3" data-position="3">
      <td>Title</td>
    </tr>
    <tr id="3" data-position="3">
      <td>Content</td>
    </tr>
    <tr id="2" data-position="2">
      <td>Title</td>
    </tr>
    <tr id="2" data-position="2">
      <td>Content</td>
    </tr>
    <tr id="2" data-position="2">
      <td>Extra content (sometimes)</td>
    </tr>
  </tbody>
</table>

Each table has a tbody and tr's. The id and data-position range is between 1 and 23. I need some kind of sorting method which keeps the title-content pairs but sort the id's ascending in each table. I found this and this tutorial, but not worked in my case (nothing happens).

My code snippet looks like this

$(".tbody").each(function(){
    $(this).html($(this).children('tr').sort(function(a, b){
        return ($(b).data('position')) < ($(a).data('position')) ? 1 : -1;
    }));
});
Stphane
  • 3,368
  • 5
  • 32
  • 47
  • What is the source of the data? Usually the source gets sorted and the table renderers simply render the data as given. – Nope Mar 21 '18 at 17:16
  • Id suggest changing how you create your table so that title and content are in the same row with width 100% you can do this with javascript fairly easily but are job is also to make our lifes easier – Joe Warner Mar 21 '18 at 17:16
  • Are you dynamically creating the tables or is it done third party? What format does the data come in? – Keegan Teetaert Mar 21 '18 at 17:31

1 Answers1

1

You could use Array.prototype.sort callback for non trivial sorting.

The demo below loops over all tables and sorts <tr>s while respecting data-position attribute ascending order (1,2,3…) keeping Titles before Contents

// Loop over all tables
$('table').each(function() {
  // Retrieve references to current table TR elements
  let collection = Array.from(this.querySelectorAll('tr'))
      .sort(function(x, y) {
        let posX = +x.dataset.position
            ,posY = +y.dataset.position;
        // Behavior when items haven't the same position
        if (posX != posY) {
            return posX > posY ? 1 : -1;
        }
        // When items have the same position
        return x.textContent.toLowerCase().trim() == 'Title' ? 1 : -1;
      })
  ;

  // Finally move items into the container using the computed order
  collection.forEach(element => {
    this.querySelector('.tbody').append(element);
  });

});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table class="deliver">
  <tbody class="tbody">
    <tr data-position="23">
      <td>Title 23</td>
    </tr>
    <tr data-position="23">
      <td>Content 23</td>
    </tr>
    <tr data-position="10">
      <td>Title 10</td>
    </tr>
    <tr data-position="10">
      <td>Content 10</td>
    </tr>
    <tr data-position="12">
      <td>Title 12</td>
    </tr>
    <tr data-position="12">
      <td>Content 12</td>
    </tr>
  </tbody>
</table>
Stphane
  • 3,368
  • 5
  • 32
  • 47