Autocomplete dropdown menu

Asked

Viewed 29 times

0

I implemented a Autocomplete system in one of my form inputs and wanted to know if I can return the result of several arrays.

The system serves for scheduling bath of a pet shop and I wanted to separate the breeds by port, for example.

const racasP1 = ["beagle", "pinscher"];

const racasp2 = ["Dálmata", "Labrador"];

I’m using the function

autocomplete(document.getElementById("myInput"), racasP1);

The input works, when I start typing the races it makes the autocomplete

<form autocomplete="off" action="/action_page.php">
<div class="autocomplete" style="width:300px;">
<label for="raça">Qual é a Raça ?</label>
<input id="myInput" type="text" name="raças">
</div>
</form>

But it only returns the suggested values of the first array and it would be interesting if it did the search in all arrays.

Here is the JS function.

const racasP1 = ["Beagle", "Dálmata" , "Labrador", "Cane Corso"];

const racasP2 = ["Cane Corso"];

const racasP3 = ["Mastiff"];

function autocomplete(inp, arr) {
    /*the autocomplete function takes two arguments,
    the text field element and an array of possible autocompleted values:*/
    var currentFocus;
    /*execute a function when someone writes in the text field:*/
    inp.addEventListener("input", function(e) {
        var a, b, i, val = this.value;
        /*close any already open lists of autocompleted values*/
        closeAllLists();
        if (!val) { return false;}
        currentFocus = -1;
        /*create a DIV element that will contain the items (values):*/
        a = document.createElement("DIV");
        a.setAttribute("id", this.id + "autocomplete-list");
        a.setAttribute("class", "autocomplete-items");
        /*append the DIV element as a child of the autocomplete container:*/
        this.parentNode.appendChild(a);
        /*for each item in the array...*/
        for (i = 0; i < arr.length; i++) {
          /*check if the item starts with the same letters as the text field value:*/
          if (arr[i].substr(0, val.length).toUpperCase() == val.toUpperCase()) {
            /*create a DIV element for each matching element:*/
            b = document.createElement("DIV");
            /*make the matching letters bold:*/
            b.innerHTML = "<strong>" + arr[i].substr(0, val.length) + "</strong>";
            b.innerHTML += arr[i].substr(val.length);
            /*insert a input field that will hold the current array item's value:*/
            b.innerHTML += "<input type='hidden' value='" + arr[i] + "'>";
            /*execute a function when someone clicks on the item value (DIV element):*/
                b.addEventListener("click", function(e) {
                /*insert the value for the autocomplete text field:*/
                inp.value = this.getElementsByTagName("input")[0].value;
                /*close the list of autocompleted values,
                (or any other open lists of autocompleted values:*/
                closeAllLists();
            });
            a.appendChild(b);
          }
        }
    });
    /*execute a function presses a key on the keyboard:*/
    inp.addEventListener("keydown", function(e) {
        var x = document.getElementById(this.id + "autocomplete-list");
        if (x) x = x.getElementsByTagName("div");
        if (e.keyCode == 40) {
          /*If the arrow DOWN key is pressed,
          increase the currentFocus variable:*/
          currentFocus++;
          /*and and make the current item more visible:*/
          addActive(x);
        } else if (e.keyCode == 38) { //up
          /*If the arrow UP key is pressed,
          decrease the currentFocus variable:*/
          currentFocus--;
          /*and and make the current item more visible:*/
          addActive(x);
        } else if (e.keyCode == 13) {
          /*If the ENTER key is pressed, prevent the form from being submitted,*/
          e.preventDefault();
          if (currentFocus > -1) {
            /*and simulate a click on the "active" item:*/
            if (x) x[currentFocus].click();
          }
        }
    });
    function addActive(x) {
      /*a function to classify an item as "active":*/
      if (!x) return false;
      /*start by removing the "active" class on all items:*/
      removeActive(x);
      if (currentFocus >= x.length) currentFocus = 0;
      if (currentFocus < 0) currentFocus = (x.length - 1);
      /*add class "autocomplete-active":*/
      x[currentFocus].classList.add("autocomplete-active");
    }
    function removeActive(x) {
      /*a function to remove the "active" class from all autocomplete items:*/
      for (var i = 0; i < x.length; i++) {
        x[i].classList.remove("autocomplete-active");
      }
    }
    function closeAllLists(elmnt) {
      /*close all autocomplete lists in the document,
      except the one passed as an argument:*/
      var x = document.getElementsByClassName("autocomplete-items");
      for (var i = 0; i < x.length; i++) {
        if (elmnt != x[i] && elmnt != inp) {
        x[i].parentNode.removeChild(x[i]);
      }
    }
  }
  /*execute a function when someone clicks in the document:*/
  document.addEventListener("click", function (e) {
      closeAllLists(e.target);
  });
  }
  • This makes it hard to help. You can’t tell what you’re struggling with. What doesn’t work? What did you try to do to fix? https://answall.com/help/minimal-reproducible-example

  • Sorry, the question was incomplete already reedited.

1 answer

0


You need to call the autocomplete function for a array which contains the concatenation of all arrays race:

const todasRacas = [...racasP1, ...racasP2, ...racasP3]; //aqui, todos os elementos dos 3 arrays são inseridos em um array maior.
autocomplete(document.getElementById("myInput"), todasRacas); // aqui é chamado o autocomplete para o array resultante.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.