I am trying to learn jQuery and JS. I want to filter the table to be the values in my arrays. The month will always be one month but the Name may have more that one name.
The results I want is:
Office | Name | Month | Quantity |
---|---|---|---|
1a | Abe D | Feb | 13 |
1a | Jon R | Feb | 12 |
$(document).ready(function(){
var names = ["Abe D", "Jon R"];
var mth = "Feb"
$("button").click(function(){
$("td:nth-child(2)").each(function(){
let tr = $(this);
let mths = tr.find('td:nth-child(3)').text();
console.log(mth ' : ' mths)
if(names.indexOf($(this).text()) == -1 || mths !== mth){
$(this).parent().hide();
}
});
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table>
<thead>
<tr>
<th>Office</th>
<th>Name</th>
<th>Month</th>
<th>Quantity</th>
</tr>
</thead>
<tr>
<td>1a</td>
<td>Abe D</td>
<td>Jan</td>
<td>10</td>
</tr>
<tr>
<td>1a</td>
<td>Abe D</td>
<td>Feb</td>
<td>13</td>
</tr>
<tr>
<td>1a</td>
<td>Jon R</td>
<td>Jan</td>
<td>9</td>
</tr>
<tr>
<td>1a</td>
<td>Jon R</td>
<td>Feb</td>
<td>12</td>
</tr>
<tr>
<td>2b</td>
<td>Eve C</td>
<td>Jan</td>
<td>13</td>
</tr>
<tr>
<td>2b</td>
<td>Eve C</td>
<td>Feb</td>
<td>14</td>
</tr>
</table>
<button>Filter</button>
How do I get the filter working?
CodePudding user response:
You already appear to have the logic to retrieve the name and month from each row of the table. Therefore to reach your goal all you need to do is use the includes()
method on the array to determine if the current name
exists within it, and a straight string comparison of the month names.
I would suggest doing this comparison on the tr
, not the child td
, as it makes the logic to hide()
/show()
them much more straightforward:
jQuery($ => {
const names = ["Abe D", "Jon R"];
const mth = "Feb"
$("button").click(function() {
$('tbody tr').hide().filter((i, tr) => {
const $tr = $(tr);
const name = $tr.children('td:nth-child(2)').text().trim();
const month = $tr.children('td:nth-child(3)').text().trim();
return names.includes(name) && month === mth;
}).show();
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table>
<thead>
<tr>
<th>Office</th>
<th>Name</th>
<th>Month</th>
<th>Quantity</th>
</tr>
</thead>
<tbody>
<tr>
<td>1a</td>
<td>Abe D</td>
<td>Jan</td>
<td>10</td>
</tr>
<tr>
<td>1a</td>
<td>Abe D</td>
<td>Feb</td>
<td>13</td>
</tr>
<tr>
<td>1a</td>
<td>Jon R</td>
<td>Jan</td>
<td>9</td>
</tr>
<tr>
<td>1a</td>
<td>Jon R</td>
<td>Feb</td>
<td>12</td>
</tr>
<tr>
<td>2b</td>
<td>Eve C</td>
<td>Jan</td>
<td>13</td>
</tr>
<tr>
<td>2b</td>
<td>Eve C</td>
<td>Feb</td>
<td>14</td>
</tr>
</tbody>
</table>
<button>Filter</button>
CodePudding user response:
The .each()
loop should loop over rows.
Then use .find()
to get the name and month fields from the row. Test them and hide the row if they don't match.
$(document).ready(function() {
var names = ["Abe D", "Jon R"];
var mth = "Feb";
$("button").click(function() {
$("tbody tr").show(); // show everything before filtering
$("tbody tr").each(function() {
let tr = $(this);
let mths = tr.find('td:nth-child(3)').text();
let name = tr.find('td:nth-child(2)').text();
if(!names.includes(name) || mths !== mth) {
$(this).hide();
}
});
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table>
<thead>
<tr>
<th>Office</th>
<th>Name</th>
<th>Month</th>
<th>Quantity</th>
</tr>
</thead>
<tbody>
<tr>
<td>1a</td>
<td>Abe D</td>
<td>Jan</td>
<td>10</td>
</tr>
<tr>
<td>1a</td>
<td>Abe D</td>
<td>Feb</td>
<td>13</td>
</tr>
<tr>
<td>1a</td>
<td>Jon R</td>
<td>Jan</td>
<td>9</td>
</tr>
<tr>
<td>1a</td>
<td>Jon R</td>
<td>Feb</td>
<td>12</td>
</tr>
<tr>
<td>2b</td>
<td>Eve C</td>
<td>Jan</td>
<td>13</td>
</tr>
<tr>
<td>2b</td>
<td>Eve C</td>
<td>Feb</td>
<td>14</td>
</tr>
</tbody>
</table>
<button>Filter</button>