I'm trying to program a search/filter function that searches through unordered list items with data-* attributes based on what the user types in.
<input type="text" placeholder="Search..." id="myInput" onkeyup="myFunction()">
<ul id="myUL">
<li><a href="#" data-keywords="photography">Digital Media Design</a></li>
<li><a href="#" data-keywords="computers">Information Technology</a></li>
<li><a href="#" data-keywords="coding">Programming</a></li>
</ul>
Here is the code I have so far that works only for one data-keywords item. I need help to get it to bring up search results based on multiple keywords.
<li><a href="#" data-keywords="photography photoshop illustrator premiere">Digital Media Design</a></li>
// Search functionality
function myFunction() {
// Declare variables
var input, filter, ul, li, a, i;
input = document.getElementById('myInput');
filter = input.value.toUpperCase();
ul = document.getElementById("myUL");
li = ul.getElementsByTagName('li');
// Loop through all list items, and hide those who don't match the search query
for (i = 0; i < li.length; i++) {
a = li[i].getElementsByTagName("a")[0];
if (a.innerHTML.toUpperCase().indexOf(filter) > -1 || $(a).data("keywords") === filter.toLocaleLowerCase()) {
li[i].style.display = "";
} else {
li[i].style.display = "none";
}
}
}
If anybody has suggestions on how I can improve the code that would be awesome!
I've made a few assumptions:
The bit that needs most explaining is that regex. It's using a standard trick for doing an and
match:
Regular Expressions: Is there an AND operator?
So if you search for digital photography
the RegExp will be equivalent to:
/(?=.*digital)(?=.*photography)/i
If you wanted searching to be or
rather than and
you'd just need to tweak the RegExp accordingly. If you wanted to do a starts-with match rather than substring you could throw in \b
before each search term (suitably escaped as \\b
in the string).
I hope the rest is pretty self-explanatory, I tried to stay close to the code in the question.
// Search functionality
function myFunction() {
// Declare variables
var input = document.getElementById('myInput'),
filter = input.value,
ul = document.getElementById('myUL'),
lis = ul.getElementsByTagName('li'),
searchTerms = filter.match(/[a-z]+/gi),
re, index, li, a;
if (searchTerms) {
searchTerms = searchTerms.map(function(term) {
return '(?=.*' + term + ')';
});
re = new RegExp(searchTerms.join(''), 'i');
} else {
re = /./;
}
// Loop through all list items, and hide those who don't match the search query
for (index = 0; index < lis.length; index++) {
li = lis[index];
a = li.firstChild;
if (re.test(a.innerHTML + ' ' + a.getAttribute('data-keywords'))) {
li.style.display = '';
} else {
li.style.display = 'none';
}
}
}
<input type="text" placeholder="Search..." id="myInput" onkeyup="myFunction()">
<ul id="myUL">
<li><a href="#" data-keywords="photography photoshop illustrator premiere">Digital Media Design</a></li>
<li><a href="#" data-keywords="computers">Information Technology</a></li>
<li><a href="#" data-keywords="coding">Programming</a></li>
</ul>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With