Search code examples
jquerytablesorter

JQuery Tablesorter text extraction not working as intended


Please find my HTML and javascript below. I am trying to sort a column in the table based on what radio button is selected.

<table id="test">
 <thead><tr><th>data</th></tr></thead>
 <tbody>
  <tr><td><span>1.00 %</span>&nbsp;<span>$5,000</span></td></tr>
  <tr><td><span>0.50 %</span>&nbsp;<span>$300.00</span></td></tr>
  <tr><td><span>1.40 %</span>&nbsp;<span>$0</span></td></tr>
  <tr><td><span>1.20 %</span>&nbsp;<span>$500</span></td></tr>
 </tbody>
</table>


$("#test").tablesorter({
            textExtractionCustom: {
                0: function (node) {
                    if ($('#radio-choice-h-2a').is(':checked')) {
                        return $(node).find("span").first().text().replace('%', '').replace(' ', '');
                    }
                    else if ($('#radio-choice-h-2b').is(':checked')) {
                        return $(node).find("span").last().text().replace('$', '').replace(',', '');
                    }
                    else {
                        return $(node).find("span").first().text().replace('%', '').replace(' ', '');
                    }
                }
            },
            headers: { 0: { sorter: "digit" }
            }
        });

if radio button radio-choice-h-2a is checked, then sort by the content in the first span in each cell and if radio button radio-choice-h-2b is selected, then sort by the content in the second span element.

This doesn't seem to be working as intended. Any help is appreciated. Thanks.


Solution

  • The textExtraction function is only called when tablesorter is initialized or updated. So, if you have a cell with data you want to sort differently depending on some indicator, you'll need to use a combination of the textExtraction and textSorter functions. You can find two different methods in the answers of this Stackoverflow question.

    Here is a demo of how it could be done

    Sort by: <label>Percent <input name="group" type="radio" checked="checked"/></label>
    or
    <label>Cost: <input name="group" type="radio"/></label>
    
    <table id="test">
        <thead><tr><th>data</th><th>blah</th></tr></thead>
     <tbody>
         <tr><td><span>1.00 %</span>&nbsp;<span>$5,000</span></td><td>abc</td></tr>
         <tr><td><span>0.50 %</span>&nbsp;<span>$300.00</span></td><td>xyz</td></tr>
         <tr><td><span>1.40 %</span>&nbsp;<span>$0</span></td><td>def</td></tr>
         <tr><td><span>1.20 %</span>&nbsp;<span>$500</span></td><td>mno</td></tr>
     </tbody>
    </table>
    

    Script

    $(function () {
    
        var $sortby = $('input[name="group"]');
    
        $('#test').tablesorter({
            theme: 'blue',
            textExtraction: {
                0: function (node, table, cellIndex) {
                    var $n = $(node).find('span');
                    // remove percent, commas and dollor signs
                    // add semi-colon between values
                    return $.trim( $n.eq(0).text().replace(/%/g,'') ) + ';' +
                        $.trim( $n.eq(1).text().replace(/[$,]/g,'') );
                }
            },
            textSorter: function (a, b) {
                // only use special sort if there is a semi-colon
                if (/;/.test(a)) {
                    var x = a.split(';'),
                        y = b.split(';'),
                        i = $sortby.index( $sortby.filter(':checked') );
                    return $.tablesorter.sortNatural(x[i], y[i]);
                } else {
                    return $.tablesorter.sortNatural(a, b);
                }
            }
        });
    
    });