简体   繁体   中英

Using Javascript to filter and hide specific table rows

I'm trying to create a filter feature that removes certain scores from a table based on min and max value.

My HTML:

<table id="historyTable">
    <tr>
        <th>Game #</th>
        <th>Date</th>
        <th>Location</th>
        <th>Score</th>
        <th>Strikes</th>
        <th>Spares</th>
    </tr>
    <tr>
        <td>299</td>
        <td>29 Feb 2016</td>
        <td>Hello World Bowling Alley</td>
        <td>202</td>
        <td>6</td>
        <td>1</td>
    </tr>
    <tr> ...same thing as above repeated a few times </tr>
</table>

I've got a button that takes the user's input min and max values and passes it to the following JS function onclick:

function updateFilter(min, max) {
var table = document.getElementById('historyTable');   
var rowCount = table.rows.length-1; // since I don't want to include the header row

for(var i = 1; i<=rowCount; i++) {
    var scoreCheck = table.rows[i].cells[3].innerHTML;
    if(scoreCheck < min || scoreCheck > max) {
        $(table.rows[i].innerHTML).hide();
    }
  }
}

However, it doesn't seem to be working. What am I doing wrong?

Example (jsFiddle)

The fiddle includes some extra functions which were created to dynamically populate the table; however, this is the crux of the fiddle:

window.updateFilter = function(min, max) {
  var table  = document.getElementById('historyTable'),
      rows   = table.tBodies[0].rows,
      fields = { score: 3 };

  // loop over rows
  for (var i = 0, n = rows.length; i < n; i++) {
    // get the numerical score; notice the unary-plus (+) for integer conversion
    var scoreCheck = +rows[i].cells[fields.score].innerText;

    if (scoreCheck < min || scoreCheck > max) {
      hidden[i] = rows[i];               // cache hidden row
      rows[i].style.display = 'none';    // hide the entire row
    } 
    // if row has a good value, make sure its shown (unhide if hidden)
    else {
      // make sure another method didn't already unhide it
      if (hidden.hasOwnProperty(i)) {
        hidden['' + i].style.display = ''; // set the styling so its visible
        delete hidden[i];                  // no longer need the value in cache
      }
    }
  }

  return false;
}

If anything, your code $(table.rows[i].innerHTML).hide() is attempting to hide a property, which probably results in an error. You probably intended to hide the entire row:

$( table.rows[i] ).hide();

These are the issues to correct:

  1. Don't use innerHTML in this selector as it will create a new element, only in memory, and act on that:

     $(table.rows[i].innerHTML) 

    Instead you should select the row element without innerHTML .

  2. Without any code to show rows again, the effect of a second filter will not be as intended, because the previously hidden rows will not appear again if they fit the second filter. So you should better use toggle instead of hide and pass the boolean setting as argument.

  3. When you read the cell content, don't use innerHTML , but the plain text content. Then also convert it to number so numerical comparisons work.

  4. As you use jQuery, you could shorten your code quite a bit.

You could use this code:

 function updateFilter(min, max) { // As you use jQuery, use it to its ful potential: $('#historyTable > tbody > tr > td:nth-child(4)').each(function() { // Don't retrieve HTML but text; convert to number with `+` var scoreCheck = +$(this).text(); // Toggle instead of hide, so it works both ways: // Don't select providing HTML, but use a TR selector. $(this).closest('tr').toggle(min <= scoreCheck && scoreCheck <= max); }); } $('#filter').click(function () { var min = +$('#min').val(); // invalid input will use 0 as minimum // Replace invalid max input with very high value, so everything will be shown var max = +$('#max').val() || 1e20; updateFilter(min, max); }); 
 th, td { border-bottom: 1px solid #ddd;} tr:hover {background-color: #f5f5f5} table {font-size: 11px} 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <table id="historyTable"> <tr> <th>Game #</th> <th>Date</th> <th>Location</th> <th>Score</th> <th>Strikes</th> <th>Spares</th> </tr> <tr> <td>299</td> <td>29 Feb 2016</td> <td>Hello World Bowling Alley</td> <td>202</td> <td>6</td> <td>1</td> </tr> <tr> <td>298</td> <td>13 March 2016</td> <td>Kuwait Open</td> <td>158</td> <td>5</td> <td>2</td> </tr> <tr> <td>297</td> <td>13 Oct 2015</td> <td>11th Columbia 300 Vienna Open</td> <td>213</td> <td>7</td> <td>1</td> </tr> <tr> <td>296</td> <td>20 Mar 2016</td> <td>Brunswick Euro Challenge</td> <td>259</td> <td>3</td> <td>2</td> </tr> </table> Min:<input id="min" size="6" value="180"> &nbsp; Max:<input id="max" size="6" value="210"> <button id="filter">Apply filter</button> 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM