TylerH TylerH - 4 months ago 9
Javascript Question

Comparing my array works until the array has multiple values in it

I'm trying to pass an array of multiple values to a function that will check if the values exist in a list of divs, and if so, mark them with a red background.

My code works when I pass an arbitrary string as a parameter, and it works when I have an array with only one value in it. However, once my array has two or more values in it, it seems to break, and there's no info in the console to clue me in.

I believe the issue is with how I wrote the comparison function, but it could also lie with how I am passing the array.



var postList = document.getElementsByClassName("post");
var userList = new Array();

//compares the user's keyword entries to the text in the divs, and marks "matching" divs with a red background
function listComparison(collection, searchText) {
for (var i = 0; i < collection.length; i++) {
if (collection[i].innerText.toLowerCase().indexOf(searchText) > -1) {
collection[i].style.backgroundColor = "red";
}
}
}

//adds user entries to an array on click and clears out the textarea
document.getElementById("save").addEventListener("click", function() {
var listEntry = document.getElementById("listEntries").value;
userList.push(listEntry);
document.getElementById("listEntries").value = "";
console.log(userList);
})

//event listener for the button that runs the collectionContains function above
document.getElementById("run").addEventListener("click", function() {
listComparison(postList, userList);
});

div {
background: #d0dbe6;
margin: 5px;
width: 50%;
}

#list {
width: 300px;
height: 100px;
}

<textarea placeholder="Enter words here one at a time and click 'Add to Filter'" id="listEntries"></textarea>
<br>
<button id="save" for="listEntries">Add to Filter</button>
<button id="run">Run Filter</button>

<div class="post">religion</div>
<div class="post">cats</div>
<div class="post">hotdogs</div>
<div class="post">babies</div>
<div class="post">test me please</div>
<div class="post">filler</div>
<div class="post">lorem ipsum</div>
<div class="post">your mom</div>
<div class="post">religion again</div>
<div class="post">build a wall</div>
<div class="post">no it's becky</div>
<div class="post">anything with religions in it is screwed!</div>




Answer

The problem lies in the fact that you're passing an array to String#indexOf() (as in collection[i].innerText.toLowerCase().indexOf(searchText)). That function expects a string as the search term, and not an array.

What's happening is that your array is getting converted into a string. When your array contains only a single string and no other elements, it works because its string representation is that same string. But when your array contains more than one element, its string representation is a comma-separated list of all those strings, and that's not going to compare correctly.

You will need to loop through the array in order to search the items in your collection for each of the strings in the array (I've renamed the parameter to make it clear you're passing an array):

var postList = document.getElementsByClassName("post");
var userList = new Array();

//compares the user's keyword entries to the text in the divs, and marks "matching" divs with a red background
function listComparison(collection, searchList) {
    for (var i = 0; i < searchList.length; i++) {
        for (var j = 0; j < collection.length; j++) {
            if (collection[j].innerText.toLowerCase().indexOf(searchList[i]) > -1) {
                collection[j].style.backgroundColor = "red";
            }
        }
    }
}

//adds user entries to an array on click and clears out the textarea
document.getElementById("save").addEventListener("click", function() {
    var listEntry = document.getElementById("listEntries").value;
    userList.push(listEntry);
    document.getElementById("listEntries").value = "";
    console.log(userList);
})

//event listener for the button that runs the collectionContains function above
document.getElementById("run").addEventListener("click", function() {
    listComparison(postList, userList);
});
div {
    background: #d0dbe6;
    margin: 5px;
    width: 50%;
}

#list {
    width: 300px;
    height: 100px;
}
<textarea placeholder="Enter words here one at a time and click 'Add to Filter'" id="listEntries"></textarea>
<br>
<button id="save" for="listEntries">Add to Filter</button>
<button id="run">Run Filter</button>

<div class="post">religion</div>
<div class="post">cats</div>
<div class="post">hotdogs</div>
<div class="post">babies</div>
<div class="post">test me please</div>
<div class="post">filler</div>
<div class="post">lorem ipsum</div>
<div class="post">your mom</div>
<div class="post">religion again</div>
<div class="post">build a wall</div>
<div class="post">no it's becky</div>
<div class="post">anything with religions in it is screwed!</div>