Reputation: 31
I'm using this javascript code, to filter search items but i want to filter a div element not just plain text.
var searchBox = document.querySelector("input");
var resultList = document.getElementById("resultList");
var resultsArray = [
"Walt Disney",
"Which color do you like?",
"Where are we?",
"Which wells are the best?",
"Who's on first?",
"Cowboys wear white",
"Wells are awesome!",
"Whoooppppeeeeee",
"Which Witch is Which",
"What's going on?",
"Well look at that!"
];
searchBox.addEventListener('keyup', function() {
var searchTerm = searchBox.value.toLowerCase();
// reset ul by removing all li items
while (resultList.hasChildNodes()) {
resultList.removeChild(resultList.lastChild);
}
// loop through array of sentences
for (var i = 0; i < resultsArray.length; i++) {
// if the array item starts with the search value AND the input box is not empty
if(resultsArray[i].toLowerCase().startsWith(searchTerm) && searchTerm != "") {
var li = document.createElement('li'); // create an li item
li.innerHTML = resultsArray[i]; // add the sentence to the new li item
resultList.append(li); // add new li item to resultList ul
}
}
// if resultList is empty after going through loop display 'no results found'
if (!resultList.hasChildNodes() && searchTerm != "") {
var li = document.createElement('li');
li.innerHTML = "no results found";
resultList.append(li);
}
});
i want to change var resultsArray items to div class items for example: "Walt Disney", to
<div class="item"><a href="walt-disney.html"><img src="images/walt-disney.png" alt="walt disney" border="0" /></a>walt disney</div>
Upvotes: 2
Views: 785
Reputation: 5085
HTMLElement
, it's a hassleTo avoid tons of for
loops and using document.createElement
, .appendChild
, and .removeChild
. I would suggest using .innerHTML
. Along with this, there is no need to rewrite the list of items in resultArray
as an object, just modify the strings to match each attribute's requirements, like so:
JavaScript Code:
const searchBox = document.querySelector("input");
const resultList = document.getElementById("resultList");
const resultsArray = [
"Walt Disney",
"Which color do you like?",
"Where are we?",
"Which wells are the best?",
"Who's on first?",
"Cowboys wear white",
"Wells are awesome!",
"Whoooppppeeeeee",
"Which Witch is Which",
"What's going on?",
"Well look at that!"
]
String.prototype.removePunctuation = function() {
return this.replace(/['"`,!?:;.]/g, '')
}
String.prototype.toSnakeCase = function() {
return this.split(' ').join('-').removePunctuation().toLowerCase()
}
searchBox.addEventListener('keyup', function() {
const searchTerm = searchBox.value.toLowerCase().trim()
resultList.innerHTML = ''
if (searchTerm) {
const renderedHTML = resultsArray
.filter(result => result.toLowerCase().indexOf(searchTerm) !== -1)
.map(result => `
<div class='item'>
<a href='${result.toSnakeCase()}.html'>
<img src='images/${result.toSnakeCase()}.png' alt='${result.removePunctuation()}' border='0'/>
</a>
</div>
`)
resultList.innerHTML = renderedHTML.length > 0 ? renderedHTML.join('') : 'No results found'
}
})
HTML Code:
<input type='text' />
<ul id='resultList'>
</ul>
Here are the changes I've made to your code:
<ul>
with .innerHTML = ''
.trim()
whitespace before searching.resultsArray
with .filter
.map
to generate the HTML.
.innerHTML
You'll also have noticed that I've created String.prototype.removePunctuation
and String.prototype.toSnakeCase
. While I wouldn't always suggest modifying String.prototype
it does make this code significantly more readable, in my opinion. It wouldn't be hard to convert this to regular functions.
Don't think it works? Test out a working version here on JSFiddle
FYI, in your question you ask for a div
with an a
that contains an img
. The only text showing is the alt='...'
attribute, so if you wanted to display the text of the resultsArray
you should just use string interpolation: ${result}
Upvotes: 1
Reputation: 22
The solution to filter an array of document elements is to look at their innerHTML
property, which is a string
that we can use to filter based on the search term.
Here's a working solution:
Notes:
querySelectorAll()
and then parsed them into an Array
using Array.prototype.slice()
.innerHTML
property of this input element list array to find the matches.var searchBox = document.querySelector("input");
var resultList = document.getElementById("resultList");
// Get the results nodes list
var resultsNodeList = document.querySelectorAll('#array-list>div');
// Parse the node list into an array list
var resultsArray = [].slice.call(resultsNodeList);
searchBox.addEventListener('keyup', function() {
var searchTerm = searchBox.value.toLowerCase();
// reset ul by removing all li items
while (resultList.hasChildNodes()) {
resultList.removeChild(resultList.lastChild);
}
// loop through array of sentences
for (var i = 0; i < resultsArray.length; i++) {
// if the array item starts with the search value AND the input box is not empty
if(searchTerm != "" && resultsArray[i].innerHTML.toLowerCase().indexOf(searchTerm) > -1) {
var li = document.createElement('li'); // create an li item
li.appendChild(resultsArray[i]); // add the sentence to the new li item
resultList.append(li); // add new li item to resultList ul
}
}
// if resultList is empty after going through loop display 'no results found'
if (!resultList.hasChildNodes() && searchTerm != "") {
var li = document.createElement('li');
li.innerHTML = "no results found";
resultList.append(li);
}
});
#array-list{
display: none;
}
#resultList{
list-style-type: none;
-webkit-padding-start: 20px;
}
<div id="array-list">
<div class="item"><a href="walt-disney.html"><img src="images/walt-disney.png" alt="walt disney" border="0" /></a>walt disney</div>
<div class="item"><a href="which-color.html"><img src="images/color.png" alt="which color" border="0" /></a>which color</div>
<div class="item"><a href="where.html"><img src="images/where.png" alt="where are we" border="0" /></a>where are we</div>
<div class="item"><a href="best-wells.html"><img src="images/best-wells.png" alt="best wells" border="0" /></a>best wells</div>
</div>
<input type="text" placeholder="Type something to search">
<br><br>
<span>Suggestions:</span>
<ul id="resultList">
</ul>
Upvotes: 0
Reputation: 782584
Change resultsArray
to an array of objects with all the information needed to construct the resulting HTML.
var resultsArray = [
{string: "Walt Disney", url: "walt-disney.html", img: "walt-disney.png", alt: "walt disney" },
{string: "Which color do you like?", url: "which-color.html", img: "which-color.png", alt: "which color" },
...
];
if (searchTerm != "") {
resultsArray.forEach(({string, url, img, alt} => {
// if the array item starts with the search value AND the input box is not empty
if(string.toLowerCase().startsWith(searchTerm)) {
var li = document.createElement('li'); // create an li item
li.innerHTML = `<div class="item"><a href="${url}"><img src="images/${img}" alt="${alt}" border="0" /></a>${string}</div>`
resultList.append(li); // add new li item to resultList ul
}
}
}
Upvotes: 1