Dónal
Dónal

Reputation: 187379

sorting table rows by columns containing markup

I'm using the tablesorter JQUery plugin to sort the rows of a HTML table by clicking on a column. In most cases, the table cells contain simple markup like <td>hello</td>, so the default behaviour works fine.

However, one column of the table contains cells like this

<td>
  <a id="1" class="festivalSubscribe " action="create" 
    controller="festivalSubscription" onclick="/* Lots of Javascript */">Not Subscribed 
  </a>

  <a id="1" class="festivalUnsubscribe hide" action="delete" 
    controller="festivalSubscription" onclick="/* Lots of JavaScript */">Subscribed 
  </a>
</td>

Each cell of this column contains two links (as above), one of which will always be invisible (the one with the hide class). I want to sort this column by the visible link text ("Not Subscribed" or "Subscribed").

The plugin provides am option to define a function, the results of which will be used to determine how to sort the column, e.g.

textExtraction: function(node) { 
  // extract data from markup and return it  
  return node.childNodes[0].childNodes[0].innerHTML; 
} 

However, I can't find a way to define this function such that it will correctly sort the simple case <td>hello</td> and the more complex case described above.

Upvotes: 1

Views: 338

Answers (4)

Mottie
Mottie

Reputation: 86453

I think @Kevin B's answer is best for the original plugin, but I wanted to add that I have forked a copy of the original plugin on github and added functionality to the textExtraction option to allow specifying columns. So this is possible.

$("table").tablesorter({ 

  // Define a custom text extraction function for each column 
  // default extraction is obtained like this: `$(node).text()` 
  textExtraction: { 
    0: function(node) {
      return $(node).find("a:visible").text();
    }
  } 
}); 

Upvotes: 2

Kevin B
Kevin B

Reputation: 95064

Try this, it should handle both cases of having child elements and not having child elements:

textExtraction: function(node) { 
  // extract data from markup and return it  
  var $node_a = $(node).find("a");
  if ($node_a.length) {
    return $node_a.filter(":visible").text();
  }
  // normal case
  return node.innerHTML; 
}

Upvotes: 2

Krzysztof
Krzysztof

Reputation: 16150

Try this:

textExtraction: function(node) { 
    return $('td :not(.hide)', node).text(); 
} 

Upvotes: 0

Konrad Dzwinel
Konrad Dzwinel

Reputation: 37913

You can grab first visible element found inside the node and extract text from it using this:

$(node).find(':visible:eq(0)').text();

Upvotes: 0

Related Questions