textExtraction update, add textAttribute & add tests. Fixes #154

This commit is contained in:
Mottie 2014-04-18 18:41:20 -05:00
parent 8f5a7a920d
commit 872325a458
4 changed files with 91 additions and 61 deletions

View File

@ -1314,14 +1314,34 @@ From the example function above, you'll end up with something similar to this HT
<td><a href="themes.html">Example</a></td>
</tr>
<tr id="textattribute">
<td><a href="#" class="permalink">textAttribute</a></td>
<td>String</td>
<td>&quot;data-text&quot;</td>
<td>This data-attribute can be added to any tbody cell and can contains alternate cell text (<span class="version">v2.16.0</span>).
<div class="collapsible">
<br>
This option contains the name of the data-attribute used by the <a href="#textextraction"><code>textExtraction</code></a> function. Add it to the cell(s) as follows:
<pre class="prettyprint lang-html">&lt;td data-text="1"&gt;First repository&lt;/td&gt;</pre>
<span class="label label-info">Note</span> This option only works when the <a href="#textextraction"><code>textExtraction</code></a> option is set to "basic".
</div>
</td>
<td></td>
</tr>
<tr id="textextraction">
<td><a href="#" class="permalink">textExtraction</a></td>
<td>String Or Function</td>
<td>&quot;simple&quot;</td>
<td>Defines which method is used to extract data from a table cell for sorting.
The built-in option is <code>&quot;simple&quot;</code> which is the equivalent of doing this inside of the textExtraction function: <code>$(node).text();</code>.
<td>&quot;basic&quot;</td>
<td>Defines which method is used to extract data from a table cell for sorting (<span class="version updated">v2.16.0</span>)
<div class="collapsible">
<br>
As of version 2.16.0,
<ul>
<li>The default text extraction method has been renamed and updated to get data from a data-attribute (set by the <a href="#textattribute"><code>textAttribute</code></a> option).</li>
<li>If you need to support older versions of IE, this may add a significant delay to the table initialization especially for large tables; in this case, set the <code>textExtraction</code> option to any name other than "basic".</li>
<li>Also, this option can now be set using a data-attribute named "data-text-extraction" on the table.</li>
</ul>
You can customize the text extraction by writing your own text extraction function "myTextExtraction" which you define like:
<pre class="prettyprint lang-js">var myTextExtraction = function(node, table, cellIndex){
// extract data from markup and return it
@ -1331,9 +1351,9 @@ From the example function above, you'll end up with something similar to this HT
$(function(){
$("#myTable").tablesorter( { textExtraction: myTextExtraction } );
});</pre>
tablesorter will pass the current table cell object for you to parse and return. Thanks to Josh Nathanson for the examples. Updated to a jQuery example by Rob G (Mottie).
tablesorter will pass the current table cell object for you to parse and return. Thanks to Josh Nathanson for the examples; updated to a jQuery example by Rob G (Mottie).
<p>Now if the text you are finding in the script above is say a number, then just include the <a href="#headers"><code>headers</code></a> sorter option to specify how to sort it. Also in this example, we will specify that the special textExtraction code is only needed for the second column (<code>1</code> because we are using a zero-based index). All other columns will ignore this textExtraction function.</p>
<p>Added <code>table</code> and <code>cellIndex</code> variables to the <code>textExtraction</code> function in version 2.1.2.</p>
<p>Added <code>table</code> and <code>cellIndex</code> variables to the <code>textExtraction</code> function in version 2.1.2 (this is not part of the original plugin).</p>
<pre class="prettyprint lang-js">$(function(){
$("table").tablesorter({
textExtraction: {
@ -1345,7 +1365,9 @@ $(function(){
1: { sorter : "digit" }
}
});
});</pre></div>
});</pre>
The built-in option is <code>&quot;basic&quot;</code> (modified v2.16.0) which is the equivalent of doing this inside of the textExtraction function: <code>$(node).text();</code>.
</div>
</td>
<td><a href="example-option-text-extraction.html">Example</a></td>
</tr>

View File

@ -64,7 +64,8 @@
emptyTo : 'bottom', // sort empty cell to bottom, top, none, zero
stringTo : 'max', // sort strings in numerical column as max, min, top, bottom, zero
textExtraction : 'simple', // text extraction method/function - function(node, table, cellIndex){}
textExtraction : 'basic', // text extraction method/function - function(node, table, cellIndex){}
textAttribute : 'data-text',// data-attribute that contains alternate cell text (used in textExtraction function)
textSorter : null, // choose overall or specific column sorter function(a, b, direction, table, columnIndex) [alt: ts.sortText]
numberSorter : null, // choose overall numeric sorter function(a, b, direction, maxColumnValue)
@ -167,20 +168,19 @@
function getElementText(table, node, cellIndex) {
if (!node) { return ""; }
var c = table.config,
t = c.textExtraction, text = "";
if (t === "simple") {
if (c.supportsTextContent) {
text = node.textContent; // newer browsers support this
} else {
text = $(node).text();
}
t = c.textExtraction || '',
text = "";
if (t === "basic") {
// check data-attribute first
text = $(node).attr(c.textAttribute) || node.textContent || node.innerText || $(node).text() || "";
} else {
if (typeof t === "function") {
if (typeof(t) === "function") {
text = t(node, table, cellIndex);
} else if (typeof t === "object" && t.hasOwnProperty(cellIndex)) {
} else if (typeof(t) === "object" && t.hasOwnProperty(cellIndex)) {
text = t[cellIndex](node, table, cellIndex);
} else {
text = c.supportsTextContent ? node.textContent : $(node).text();
// previous "simple" method
text = node.textContent || node.innerText || $(node).text() || "";
}
}
return $.trim(text);
@ -928,8 +928,6 @@
$.data(table, "tablesorter", c);
if (c.debug) { $.data( table, 'startoveralltimer', new Date()); }
// constants
c.supportsTextContent = $('<span>x</span>')[0].textContent === 'x';
// removing this in version 3 (only supports jQuery 1.7+)
c.supportsDataObject = (function(version) {
version[0] = parseInt(version[0], 10);
@ -961,6 +959,8 @@
c.$table.attr('aria-labelledby', 'theCaption');
}
c.widgetInit = {}; // keep a list of initialized widgets
// change textExtraction via data-attribute
c.textExtraction = c.$table.attr('data-text-extraction') || c.textExtraction || 'basic';
// build headers
buildHeaders(table);
// fixate columns if the users supplies the fixedWidth option

View File

@ -36,7 +36,7 @@
<li>Include <a href="https://github.com/overset/javascript-natural-sort">natural sort</a> unit tests?</li>
</ul>
<table id="table1" class="tester">
<table id="table1" class="tester" data-text-extraction="basic">
<thead>
<tr><th class="{sortValue:'zzz', poe:'nevermore'}">test-head</th><th>num</th></tr>
</thead>
@ -44,9 +44,9 @@
<tr><th>test-foot</th><th>txt</th></tr>
</tfoot>
<tbody>
<tr><td>test2</td><td>x2</td></tr>
<tr><td>test1</td><td>x3</td></tr>
<tr><td>test3</td><td>x1</td></tr>
<tr><td data-text="test2">ignored</td><td>x2</td></tr>
<tr><td data-text="test1">ignored</td><td>x3</td></tr>
<tr><td data-text="test3">ignored</td><td>x1</td></tr>
</tbody>
<tbody class="tablesorter-infoOnly">
<tr><td colspan="3">Info</td></tr>
@ -73,7 +73,7 @@
</tbody>
</table>
<table id="table3" class="tester">
<table id="table3" class="tester" data-text-extraction="x">
<thead>
<tr>
<th>1</th>
@ -83,7 +83,7 @@
</tr>
</thead>
<tbody>
<tr><td>A43</td><td>-35</td><td>01</td><td>-.1</td></tr>
<tr><td data-text="x43">A43</td><td>-35</td><td>01</td><td>-.1</td></tr>
<tr><td>A255</td><td>33</td><td>02</td><td>N/A #1</td></tr>
<tr><td>A33</td><td>2</td><td>03</td><td>N/A #2</td></tr>
<tr><td>A1</td><td>-5</td><td>04</td><td>-8.4</td></tr>

View File

@ -118,8 +118,6 @@ EVENTS:
*/
$(function(){
// keep stuff in order; yeah I know every test needs to be atomic - bleh
QUnit.config.reorder = false;
var ts = $.tablesorter,
$table1 = $('#table1'),
@ -136,7 +134,7 @@ $(function(){
sortIndx = 0,
updateIndx = 0,
updateCallback = 0,
events = ['sortStart', 'sortBegin', 'sortEnd' ],
events = ['sortStart', 'sortBegin', 'sortEnd', ' '],
returnTime = function(string){
return new Date(string).getTime();
},
@ -146,14 +144,6 @@ $(function(){
.bind('tablesorter-initialized', function(){
init = true;
})
.bind( events.join(' '), function(e){
if (e.type === events[sortIndx%3]) {
sortIndx++;
}
})
.bind('updateComplete', function(){
updateIndx++;
})
.tablesorter();
$table2.tablesorter({
@ -192,19 +182,7 @@ $(function(){
}
});
$table5
.bind( events.join(' '), function(e){
if (e.type === events[sortIndx%3]) {
sortIndx++;
}
})
.bind('updateComplete', function(){
updateIndx++;
})
.tablesorter();
// ensure all sort events fire on an empty table
$table5.trigger('sorton', [ [[0,0]] ]);
$table5.tablesorter();
/************************************************
JSHint testing
@ -405,6 +383,17 @@ $(function(){
});
test( "textExtraction Method", function() {
expect(2);
$table1.trigger('sorton', [[[ 0,0 ]]]);
tester.cacheCompare( table1, 0, [ 'test1', 'test2', 'test3', '', 'testa', 'testb', 'testc' ], 'from data-attribute' );
$table3.trigger('sorton', [[[ 0,1 ]]]);
tester.cacheCompare( table3, 0, [ '', 'a255', 'a102', 'a87', 'a55', 'a43', 'a33', 'a10', 'a02', 'a1' ], 'ignore data-attribute' );
});
/************************************************
test parser cache
************************************************/
@ -472,24 +461,41 @@ $(function(){
test( "sort Events", function(){
expect(1);
$table1.add($table5).bind( events.join('.testing '), function(e){
if (e.type === events[sortIndx%3]) {
sortIndx++;
}
});
$table1.trigger('sorton', [[[ 0,0 ]]]);
$table1.trigger('sorton', [[[ 1,0 ]]]);
// ensure all sort events fire on an empty table
$table5.trigger('sorton', [ [[0,0]] ]);
$table1.add($table5).unbind( events.join('.testing ') );
// table1 sorted twice in the above test; sortIndx = 9 then empty table5 x1 (total = 3 events x 3)
equal( sortIndx, 9, 'sortStart, sortBegin & sortEnd fired in order x3; including empty table' );
equal( sortIndx, 9, 'sortStart, sortBegin & sortEnd fired in order x2; including empty table' );
});
/************************************************
test update methods
************************************************/
test( "parser cache; update methods & callbacks", function() {
expect(5);
expect(7);
c1.ignoreCase = true;
// updateAll
$table1
.trigger('sorton', [ [[0,1]] ])
.bind('updateComplete.testing', function(){ updateIndx++; })
.find('th:eq(1)').removeAttr('class').html('num').end()
.find('td:nth-child(2)').html(function(i,h){
return h.substring(1);
});
$table1.trigger('updateAll', [false, function(){
$table1
.trigger('updateAll', [false, function(){
updateCallback++;
var nw = $table1.find('th:eq(1)')[0],
hc = c1.headerContent[1] === 'num',
@ -502,7 +508,8 @@ $(function(){
// addRows
t = $('<tr class="temp"><td>testd</td><td>7</td></tr>');
$table1.find('tbody:last').append(t);
$table1
.find('tbody:last').prepend(t);
$table1.trigger('addRows', [t, true, function(){
updateCallback++;
tester.cacheCompare( table1, 'all', [ 'test3', 1, 'test2', 2, 'test1', 3, '', '', 'testd', 7, 'testc', 4, 'testb', 5, 'testa', 6 ], 'addRows method' );
@ -523,18 +530,19 @@ $(function(){
tester.cacheCompare( table1, 'all', [ 'test3', 1, 'test2', 2, 'test1', 3, '', '', 'testc', 4, 'testb', 5, 'testa', 6 ], 'update method' );
}]);
// update empty table
$table5.trigger('update', [false, function(){
updateCallback++;
}]);
$table5
.bind('updateComplete.testing', function(){ updateIndx++; })
.trigger('update', [true, function(){
updateCallback++;
tester.cacheCompare( table5, 'all', [], 'update method on empty table' );
}]);
});
$table1.add($table5).unbind('updateComplete.testing');
test( "UpdateComplete Event", function(){
expect(1);
// table1 updated 4x in the above test
// table5 updated 1x
equal( updateIndx, updateCallback, 'updatedComplete and update callback functions working properly' );
});
/************************************************