I have a search with filter that narrows down data as expected. I would like to implement the functionality of hiding all the data by default, and only show results when they match a search. At the moment if nothing is typed everything is shown. The list will be very long once all data will be added, hence the request. Many thanks.
$(document).ready(function(){
$("#search-box").on("keyup", function() {
var value = $(this).val().toLowerCase();
var filter = $('#search-filter').val().toLowerCase();
if(filter == "listitem") {
$(".listitem").filter(function() {
$(this).toggle($(this).text().toLowerCase().indexOf(value) > -1)
});
} else {
$(".td-" filter).filter(function() {
$(this).parent().toggle($(this).text().toLowerCase().indexOf(value) > -1)
});
}
});
$('#search-filter').on("change",function(){
var value = $("#search-box").val().toLowerCase();
var filter = $(this).val().toLowerCase();
if(filter == "listitem") {
$(".listitem").filter(function() {
$(this).toggle($(this).text().toLowerCase().indexOf(value) > -1)
});
} else {
$(".td-" filter).filter(function() {
$(this).parent().toggle($(this).text().toLowerCase().indexOf(value) > -1)
});
}
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div >
<div >
<div >
<select id="search-filter" name="search-filter">
<!--<option value="listitem">All</option>-->
<option value="" disabled selected>Search by</option>
<option value="name">Name</option>
<option value="surname">Surname</option>
</select>
</div>
<input id="search-box" type="text" name="search" placeholder="Type here..." required="required"/>
</div>
<table>
<thead>
<tr>
<th>Name</th>
<th>Surname</th>
</tr>
</thead>
<tbody>
<tr >
<td >Jane</td>
<td >Doe</td>
</tr>
<tr >
<td >Dela</td>
<td >Cruz</td>
</tr>
</tbody>
</table>
</div>
CodePudding user response:
Start by hiding everything. Then use an if
statement to test if the search value is not empty, and show the matching elements.
I've also pulled the filtering code out into a named function, so we don't have to repeat it in both event listeners.
.filter()
shouldn't be used to execute operations on each element, that should be done with .each()
. But in this case you can use it to return a new collection that's just the matching elements, and you can then show them all together.
function filter_items(value, filter) {
$(".listitem").hide();
if (value != '') {
if (filter == "listitem") {
$(".listitem").filter(function() {
return $(this).text().toLowerCase().includes(value)
}).show();
} else {
$(".td-" filter).filter(function() {
return $(this).text().toLowerCase().includes(value)
}).closest(".listitem").show();
}
}
}
$(document).ready(function() {
$("#search-box").on("keyup", function() {
var value = $(this).val().toLowerCase();
var filter = $('#search-filter').val().toLowerCase();
filter_items(value, filter);
});
$('#search-filter').on("change", function() {
var value = $("#search-box").val().toLowerCase();
var filter = $(this).val().toLowerCase();
filter_items(value, filter);
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div >
<div >
<div >
<select id="search-filter" name="search-filter">
<!--<option value="listitem">All</option>-->
<option value="" disabled selected>Search by</option>
<option value="name">Name</option>
<option value="surname">Surname</option>
</select>
</div>
<input id="search-box" type="text" name="search" placeholder="Type here..." required="required" />
</div>
<table>
<thead>
<tr>
<th>Name</th>
<th>Surname</th>
</tr>
</thead>
<tbody>
<tr >
<td >Jane</td>
<td >Doe</td>
</tr>
<tr >
<td >Dela</td>
<td >Cruz</td>
</tr>
</tbody>
</table>
</div>