问题
I have a table
and want to filter the last two columns, Archived
and Full Entry
. The 4th column archived will either have a date or be empty. The 5th column full entry will either be true or false. I have two dropdowns, the logic of the first dropdown should:
If Archived is selected, filter the 4th column to show only rows where 4th column is empty.
If Not archived is selected, filter 4th column to show only rows where 4th column is not empty.
If All selected, show all in this column
And
If True is selected for second dropdown, filter 5th column to show only rows where 5th column contains true.
.... If false filter 5th column where rows equal to false...
... If all show all in 5th column.
I cannot get the script to work for Archive. Thanks for any help
$(function() {
$('#archive').change(function() {
if ($(this).val() == "archived") {
$("#filter").find("td:nth-child(3):not(:empty)")
} else {
$("#filter").find("td:nth-child(3):empty")
}
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<label for="archive">Filter Archive</label>
<select id="archive" name="archive">
<option value="all">All</option>
<option value="archived">Archived</option>
<option value="not-archived">Not Archived</option>
</select>
<label for="type">Filter Full Entry</label>
<select id="type" name="type">
<option value="all">All</option>
<option value="true" selected>True</option>
<option value="false" selected>False</option>
</select>
<table class="table" style="width: 30%" id="filter">
<thead>
<tr>
<th>Ref</th>
<th>Edit</th>
<th>Name</th>
<th>Archived</th>
<th>Full Entry</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>2</td>
<td>3</td>
<td>4</td>
<td>True</td>
</tr>
<tr>
<td>a</td>
<td>b</td>
<td>c</td>
<td></td>
<td>False</td>
</tr>
<tr>
<td>5</td>
<td>5</td>
<td>6</td>
<td></td>
<td>True</td>
</tr>
</tbody>
</table>
回答1:
Your logic is on the right lines, but just incomplete. Also note that the archived
column is nth-child(4)
, not 3
, as it's 1-based, not 0-based.
To simplify the logic you can create a function which runs when either of the filter select
elements are changed. This function will first show all rows and then hide all those which do not match the filter option chosen, like this:
$(function() {
$('#archive, #type').change(function() {
filterTable($('#archive').val(), $('#type').val());
});
});
function filterTable(archive, entry) {
var $rows = $('#filter tbody tr').show();
if (archive == "archived") {
$rows.filter(":has(td:nth-child(4):empty)").hide()
} else if (archive == "not-archived") {
$rows.filter(":has(td:nth-child(4):not(:empty))").hide()
}
if (entry == "true") {
$rows.filter(":has(td:nth-child(5):contains('False'))").hide()
} else if (entry == "false") {
$rows.filter(":has(td:nth-child(5):contains('True'))").hide()
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<label for="archive">Filter Archive</label>
<select id="archive" name="archive">
<option value="all">All</option>
<option value="archived">Archived</option>
<option value="not-archived">Not Archived</option>
</select>
<label for="type">Filter Full Entry</label>
<select id="type" name="type">
<option value="all">All</option>
<option value="true" selected>True</option>
<option value="false" selected>False</option>
</select>
<table class="table" style="width: 30%" id="filter">
<thead>
<tr>
<th>Ref</th>
<th>Edit</th>
<th>Name</th>
<th>Archived</th>
<th>Full Entry</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>2</td>
<td>3</td>
<td>4</td>
<td>True</td>
</tr>
<tr>
<td>a</td>
<td>b</td>
<td>c</td>
<td></td>
<td>False</td>
</tr>
<tr>
<td>5</td>
<td>5</td>
<td>6</td>
<td></td>
<td>True</td>
</tr>
</tbody>
</table>
回答2:
You could use a filter
$(function() {
var $archive = $('#archive');
var $type = $('#type');
var $rows = $("#filter").find("tbody tr"); // cache this in a var for better performance (unless you have dynamic added rows)
$archive.change(filterTable);
$type.change(filterTable);
function filterTable() {
var archiveValue = $archive.val();
var typeValue = $type.val();
$rows.hide() // hide all rows first
.filter(function() { // filter out the rows to show
if (archiveValue === 'all' && typeValue === 'all') {
return true; // show all rows if no filters selected
} else if (archiveValue === 'all') {
return $(this).children().eq(4).text().toLowerCase() === typeValue; // show only matching type filters if archive filters is all
} else {
var text = $(this).children().eq(3).text().trim();
isArchived = archiveValue === 'archived' ? text !== '' : text === '';
if (typeValue === 'all') {
return isArchived; // if type filters is all, just show archive filtered contnt
} else {
return $(this).children().eq(4).text().toLowerCase() === typeValue && isArchived; // filter by both archive and type
}
}
}).show();
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<label for="archive">Filter Archive</label>
<select id="archive" name="archive">
<option value="all">All</option>
<option value="archived">Archived</option>
<option value="not-archived">Not Archived</option>
</select>
<label for="type">Filter Full Entry</label>
<select id="type" name="type">
<option value="all" selected>All</option>
<option value="true">True</option>
<option value="false">False</option>
</select>
<table class="table" style="width: 30%" id="filter">
<thead>
<tr>
<th>Ref</th>
<th>Edit</th>
<th>Name</th>
<th>Archived</th>
<th>Full Entry</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>2</td>
<td>3</td>
<td>4</td>
<td>True</td>
</tr>
<tr>
<td>a</td>
<td>b</td>
<td>c</td>
<td></td>
<td>False</td>
</tr>
<tr>
<td>5</td>
<td>5</td>
<td>6</td>
<td></td>
<td>True</td>
</tr>
</tbody>
</table>
来源:https://stackoverflow.com/questions/53867724/filter-table-with-dropdown