Автозаполнение не работает с динамически сгенерированными полями формы - PullRequest
1 голос
/ 20 октября 2019

Я хочу создать форму заказа меню, в которой пользователи могут динамически вводить нужные элементы, добавляя новые поля в форму с помощью кнопки «Добавить элемент». Я также хочу, чтобы поля ввода имели автозаполнение, чтобы помочь пользователю выбрать правильное имя для элемента. В настоящее время у меня есть две функции, работающие независимо, так как функция автозаполнения работает с первым полем ввода по умолчанию, и я могу добавлять новые поля, но новые динамически генерируемые поля не имеют автозаполнения, и я не уверен, почему.

Автозаполнение при работе с первым полем ввода:

autocomplete working

Добавление новых полей ввода при работе:

new input fields

Автозаполнение НЕ работает с новыми полями ввода:

not working on NEW fields

Я вызвал функцию автозаполнения в коде, где я генерирую новое поле, иЯ звоню конкретно по идентификатору нового поля, которое я сгенерировал, но по какой-то причине оно все еще не работает.

Код для автозаполнения:

var items = JSON.parse(document.getElementById('items').textContent);
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);
 });
 }
 autocomplete(document.getElementById("myInput1"), items);
  /* Add rows to form dynamically */

Добавление полей:

var counter = 1;
 $("#addrow").on("click", function () {
  if (counter < 20){
    counter++;
    var newRow = $("<tr>");
    var cols = "";
    var optionList;
    for (var x = 1; x < 21; x++) {
        optionList += '<option value=' + x + '>' + x + '</option>';
    }
    cols += '<td><h3>' + counter + '.</h3></td>'
    cols += '<td><input type="search" id="myInput' + counter + '" 
    class="myInput form-control" placeholder = "Enter Item" 
    name="itemName' + counter + '" autocomplete="off"/></td>';
    cols += '<td><select class = "custom-select" name = "itemQuantity' + 
    counter + '">' + optionList +'</select></td>';
    cols += '<td><input type="button" class="ibtnDel btn btn-md btn- 
    danger "  value="Delete"></td>';

    newRow.append(cols);
    $("table.order-list").append(newRow);

    var element = document.getElementById("myInput"+counter);
    console.log(element);

    autocomplete(document.getElementById("myInput"+counter), items);

 }
 });

$("table.order-list").on("click", ".ibtnDel", function (event) {
   $(this).closest("tr").remove();
counter -= 1 
});

По сути, я хочу, чтобы все мои динамически сгенерированные поля ввода работали так же, как мое поле ввода по умолчанию.

Пожалуйста, не стесняйтесь просить меня уточнить любой аспект моего кода или предоставить больше кода. Спасибо за любую помощь, спасибо.

...