skip to Main Content

I am really new to programming and trying to make my first site using the basics. I am trying to do a search/filter bar to search/filter through the set of images on my web. Lets go with "Josh". If I search "Josh", it finds it, but if I search "josh" or "JOsh" it does not.

 function search(){
  var searchText = document.getElementById("searchInput").value;
  var images = document.querySelectorAll(".image_container > img");
  
  if(searchText.length > 0){
    images.forEach((image) => {
      image.classList.add("hide");
      if(image.dataset.tags.indexOf(searchText) > -1){
        image.classList.remove("hide");
      }
    });
  }else{
    images.forEach((image) => {
        image.classList.remove("hide");
    });
  }
}

I tried using the .toLowerCase() before .indexOf but that just makes all the search lowercase and if I try to use it somewhere else it just straight up does not work. Any help would be appreciated.

4

Answers


  1. As stated by Nina Scholz, you need to normalize the string.

    Your initial move was partially correct, you stated that you had used .toLowerCase() before .indexOf, what you need to do, is to also make the search value input lowercase. Then everything will work as intended.

    function search(){
     //Normalize your search text to lowercase
      var searchText = (document.getElementById("searchInput").value).toLowerCase();
      var images = document.querySelectorAll(".image_container > img");
      
      if(searchText.length > 0){
        images.forEach((image) => {
          image.classList.add("hide");
          //Normalize your search targets to lowercase
          if((image.dataset.tags).toLowerCase().indexOf(searchText) > -1){
            image.classList.remove("hide");
          }
        });
      }else{
        images.forEach((image) => {
            image.classList.remove("hide");
        });
      }
    }
    Login or Signup to reply.
  2. You can’t use .indexOf() in this case.
    You could use the array function some() (mdn link).

    There are many ways of achieving what you want here. Personally, I wouldn’t use forEach or some at all; they are 100x – 1000x slower than just using a for(){} loop. (But if you only have a few images with a couple tags or something, it won’t matter.)

    function search(){
        var searchTextLowerCase = document.getElementById("searchInput").value.toLowerCase();
        var images = document.querySelectorAll(".image_container > img");
        
        if(searchTextLowerCase.length > 0){
          images.forEach((image) => {
            image.classList.add("hide");
            if( image.dataset.tags.some( tag => tag.toLowerCase() === searchTextLowerCase ) ){
              image.classList.remove("hide");
            }
          });
        }else{
          images.forEach((image) => {
              image.classList.remove("hide");
          });
        }
      }
      
    
    Login or Signup to reply.
  3. for strings you can use regular expression that match your input no matter if its lower or upper and use search method instead of indexOf, this is how you can do it:

    function search(){
        var searchText = document.getElementById("searchInput").value;
        var images = document.querySelectorAll(".image_container > img");
        var regex = new RegExp(searchText, "i");
    
        if(searchText.length > 0){
          images.forEach((image) => {
            image.classList.add("hide");
            if(image.dataset.tags.search(regex) > -1){
              image.classList.remove("hide");
            }
          });
        }else{
          images.forEach((image) => {
              image.classList.remove("hide");
          });
        }
    }
    

    for arrays you need to use test method instead of search as follows

    if(arr.map(el => regex.test(el)){
      //.....
    }
    
    Login or Signup to reply.
  4. Make both upper case or both lower case, then find index of searchText in tag

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search