Reputation: 19366
I'm trying to initiate a search (or rather filter) on keypress
for an image library. The user starts typing in the name of an image, and any image name that doesn't match the search term gets hidden:
<div id="abc" data-imgName="abc"></div>
<div id="abc2" data-imgName="abc2"></div>
<div id="xyz" data-imgName="xyz"></div>
So if a user starts typing in "ab", then: $('#xyz').hide();
How can I do this? Can I use regex on an attribute?
Upvotes: 0
Views: 798
Reputation: 76003
//bind an event handler to the text input for the keyup event (so the value will have changed by the time this event fires)
$('input[type="text"]').on('keyup', function (event) {
//convert the value of the text box to lowercase
this.value = this.value.toLowerCase();
//cache the elements that match the search
var good_to_go = $('[data-imgName*=' + $(this).val() + ']').show();
//hide all the elements that do not match the search
$('[data-imgName]').not(good_to_go).hide();
});
There is probably a way to do this that performs better but this takes the value of the text input and finds all the elements with the data-imgName
attribute that contains the value of the text input. It then finds all the elements with the data-imgName
attribute and hides all of the elements that have not been found already.
If you have a parent element to all of the searched elements, you should start all the selectors with it to avoid searching the entire DOM:
var $container = $('#container-id');
$('input[type="text"]').on('keyup', function (event) {
this.value = this.value.toLowerCase();
if (this.value == '') {
$container.children().show();
} else {
var good_to_go = $container.find('[data-imgName*="' + this.value + '"]').show();
$container.find('[data-imgName]').not(good_to_go).hide();
}
});
Notice that this example also checks if the value of the text box is nothing, if so then it shows all of the searched elements.
Here are docs for the *=
(contains) selector: http://api.jquery.com/attribute-contains-selector/
Here are docs for the .not()
function: http://api.jquery.com/not
Here is a working demo: http://jsfiddle.net/HRjHV/3/
Upvotes: 5
Reputation: 12566
<div id="image_holder">
<div id="abc" data-imgName="abc">a</div>
<div id="abc2" data-imgName="abc2">b</div>
<div id="xyz" data-imgName="xyz">x</div>
</div>
<br>
<input type="text" id="search">
<script type="text/javascript">
$(document).ready(function() {
$("#search").keyup(function() {
var term = $(this).val();
$("#image_holder").find("div").css("display", "block");
$("#image_holder").find("div").each(function() {
if ($(this).attr("data-imgName").indexOf(term) < 0) {
$(this).css("display", "none");
}
});
});
});
</script>
Here is a fiddle for you: http://jsfiddle.net/yASQW/
Upvotes: 0
Reputation: 6269
you have to cycle through all your divs each time, then its possible.
Adjust you html a little:
<div class="searchImg" data-imgName="abc"></div>
<div class="searchImg" data-imgName="abc2"></div>
<div class="searchImg" data-imgName="xyz"></div>
then you can cycle through them:
var searchTerm = "abc";
$("div.searchImg").each(function() {
if($(this).attr("data-imgName").indexOf(searchTerm)) == -1)
$(this).hide();
else
$(this).show();
});
Upvotes: 0
Reputation: 8444
$('#yourField').on('keyup', function() {
$('.image').each(function() {
if ($(this).attr('data-imgName').indexOf($('#yourField').val()) === -1) {
$(this).hide();
} else {
$(this).show();
}
});
});
Edit: I'll leave this for reference but @Jasper's solution is much more efficient.
Upvotes: 0