简体   繁体   中英

Jquery autocomplete input text created dynamically

I'm trying to do a code in order that users can add an unlimited numbers of occupations via a "+" button which create input text occupation[]. But when the new input text is created, he cannot be autocomplete like the others natives input (not created dynamically).

So how to add correctly new input text for permit autocompletion of all the input ?

Here is my Jquery code for autocomplete:

    $('input[name="occupation[]"]').on("keyup", function(){
    var occup = $(this).val();
    var currentElement = $(this);       
    if(occup != ""){ 
        $.ajax({
            type: "GET",
            url: "page_geneoccup.php",
            data: {"occup":occup},
            dataType: 'json',
            success:function(responseData){
                var liste_occup=responseData; 
                $(currentElement).autocomplete({
                    source: liste_occup
                }); 
                return;
            },
            error:function(XMLHttpRequest, textStatus, errorThrow){
                console.log("Error: " + XMLHttpRequest.status + errorThrow );
                return;
            }
        });
    }
});

PS: Sorry for my english...

Best regards


My new code but, functioning for the first input and not for the others:

   <html lang="fr">
<head>
<meta charset="utf-8" />         
<link rel="stylesheet" href="//code.jquery.com/ui/1.11.4/themes/smoothness/jquery-ui.css">
<script src="//code.jquery.com/jquery-1.10.2.js"></script>
<script src="//code.jquery.com/ui/1.11.4/jquery-ui.js"></script>
<script>


    var oAutoCompleteElements = {
    addInputEvents:function(newInputs){
        var r_newInputs = $(newInputs);
        $(newInputs).each(function(i, oInput){
            $(oInput).off();
            $(oInput).on('keyup',function(){
                var occup = $(oInput).val();
                if(occup){
                $.ajax({
                type: "GET",
                url: "page_geneoccup.php",
                data: {"occup":occup},
                dataType: 'json',
                success:function(responseData){
                    var liste_occup=responseData; 
                    $(oInput).autocomplete({
                        source: liste_occup
                    }); 
                    return;
                },
                error:function(XMLHttpRequest, textStatus, errorThrow){
                    console.log("Error: " + XMLHttpRequest.status + errorThrow );
                    return;
                }
            });
                }
            });
        });
    },
    addButtonEvents:function(){
        $('#addNewInput').on('click',function(){
            oAutoCompleteElements.addNewInput();
        });
    },
    addNewInput:function(){
        newInput ='<input type="text" name="occupation[]"/>';
        $('#occupationsContainer').append(newInput);
          oAutoCompleteElements.addInputEvents($('input[name="occupation[]"]:last'));
    },
    init:function(){
       this.addButtonEvents();
       this.addInputEvents($('input[name="occupation[]"]'));
    }
};

$(function(){
    oAutoCompleteElements.init();
});


var counter = 1;
function addInput()
{
          var target        = document.getElementById('occupationsContainer');
          var newdiv        = document.createElement('div');
          var newdivname    = 'Div' + counter;
          newdiv.setAttribute('id',newdivname);
          content = newdiv.innerHTML;
          content +='<input name="occupation[]">';
          content +='<a id="AccountDelete" href="#" onclick="removeInput(\'' + newdivname + '\');">[Supprimer cet enfant]</a><br><br><hr><br><br>';
          newdiv.innerHTML = content;
          target.appendChild(newdiv);
          counter++;
}

function removeInput(idInput)
{
    var elmt = document.getElementById(idInput);
    elmt.parentNode.removeChild(elmt);
}   
    </script>

    </head>
    <body>



<div  id="occupationsContainer">
<input name="occupation[]">
<input type="button"  id="addNewButton" value="add" onclick="addInput();">
</div>

    </body>
    </html>

A last idea in order to definitely solve this problem ?

Regards

You could make a container (a form, div, whatever) for all the inputs and use event delegation . This would allow you to not create event listeners for each of the inputs.

Your example code would then be:

<!DOCTYPE html>
<html lang="fr">

<head>
  <meta charset="utf-8" />
  <link rel="stylesheet" href="//code.jquery.com/ui/1.11.4/themes/smoothness/jquery-ui.css" />
  <script src="//code.jquery.com/jquery-1.10.2.js"></script>
  <script src="//code.jquery.com/ui/1.11.4/jquery-ui.js"></script>
  <script>
    var addNewInput = function() {
      $('#occupationsContainer').append('<input name="occupation[]" />');
    }

    /* delete last input from occupationsContainer, 
       but make sure it's not the first one */
    var deleteInput = function() {
      $('#occupationsContainer>input').not(':first').remove(':last');
    }

    /* this listens for keyup event on any input in the element
       with id occcupationsContainer */
    $('#occupationsContainer').on("keyup", "input", function() {
      var occup = $(this).val();
      var currentElement = $(this);
      if (occup != "") {
        $.ajax({
          type: "GET",
          url: "page_geneoccup.php",
          data: {
            "occup": occup
          },
          dataType: 'json',
          success: function(responseData) {
            var liste_occup = responseData;
            $(currentElement).autocomplete({
              source: liste_occup
            });
            return;
          },
          error: function(XMLHttpRequest, textStatus, errorThrow) {
            console.log("Error: " + XMLHttpRequest.status + errorThrow);
            return;
          }
        });
      }
    });
  </script>
</head>

<body>
  <button id="addBtn" onclick="addNewInput()">Add</button>
  <button id="removeBtn" onclick="deleteInput()">Remove</button>
  <div id="occupationsContainer">
    <input name="occupation[]" />
  </div>

</body>

</html>

the new element is not part of the DOM at the moment you call DOM ready, and will not be part of the array you create in $('input[name="occupation[]"]');

You should add the element to the array, either by reinitiating the function you use to add the autocompleter to your elements.

I removed this part because it was getting to freaking long.

In your body you only need an element containing your inputs with id="occupationsContainer" and a button with id="addNewButton"

and that should do what you want ;)

final solution:

Also remove the button from the occupationsContainer element,And add it outside of those brackets, this will make sure that element is always beneath the inputs.


var oAutoCompleteElements = {
    counter:1,
    addInputEvents:function(newInputs){
       var r_newInputs = $(newInputs);
       $(newInputs).each(function(i, oInput){
           $(oInput).off();
           $(oInput).on('keyup',function(){
              var occup = $(oInput).val();
              if(occup){
                  console.log('a call to your autocompleter list');
              }
          });

         //add events to the new deleteButton
         var deleteInput = $(oInput).parent().find('.deleteInput');
         $(deleteInput).each(function(i, oDelete){
              $(oDelete).on('click',function(){
                  oAutoCompleteElements.removeInput($(oInput).parent());
              });
          });
       });
    },
    //add events to the add button,
    addButtonEvents:function(){
        $('#addNewInput').on('click',function(){
            oAutoCompleteElements.addNewInput();
        });
    },
    //add a new input
    addNewInput:function(){
        newInput ='<div id="Div' + oAutoCompleteElements.counter + '"><input    type="text" name="occupation[]"/><a class="deleteInput">[Supprimer cet enfant]</a></div>';
         oAutoCompleteElements.counter ++ ;
         $('#occupationsContainer').append(newInput);

         oAutoCompleteElements.addInputEvents($('input[name="occupation[]"]:last'));
    },
    //remove an input
    removeInput:function(oInput_container){
       $(oInput_container).remove();
       oAutoCompleteElements.counter --;
    },
    init:function(){
       this.addButtonEvents();
       this.addInputEvents($('input[name="occupation[]"]'));
    }
};

$(function(){
    oAutoCompleteElements.init();
});

The solution:

<html lang="fr">
<head>
<meta charset="utf-8" />         
<link rel="stylesheet" href="//code.jquery.com/ui/1.11.4/themes/smoothness/jquery-ui.css">
<script src="//code.jquery.com/jquery-1.10.2.js"></script>
<script src="//code.jquery.com/ui/1.11.4/jquery-ui.js"></script>
<script>


    var oAutoCompleteElements = {
    addInputEvents:function(newInputs){
        var r_newInputs = $(newInputs);
        $(newInputs).each(function(i, oInput){
            $(oInput).off();
            $(oInput).on('keyup',function(){
                var occup = $(oInput).val();
                if(occup){
                $.ajax({
                type: "GET",
                url: "page_geneoccup.php",
                data: {"occup":occup},
                dataType: 'json',
                success:function(responseData){
                    var liste_occup=responseData; 
                    $(oInput).autocomplete({
                        source: liste_occup
                    }); 
                    return;
                },
                error:function(XMLHttpRequest, textStatus, errorThrow){
                    console.log("Error: " + XMLHttpRequest.status + errorThrow );
                    return;
                }
            });
                }
            });
        });
    },
    addButtonEvents:function(){
        $('#addNewInput').on('click',function(){
            oAutoCompleteElements.addNewInput();
        });
    },
    addNewInput:function(){
        newInput ='<input type="text" name="occupation[]"/>';
        $('#occupationsContainer').append(newInput);
          oAutoCompleteElements.addInputEvents($('input[name="occupation[]"]:last'));
    },
    init:function(){
       this.addButtonEvents();
       this.addInputEvents($('input[name="occupation[]"]'));
    }
};

$(function(){
    oAutoCompleteElements.init();
});



    </script>

    </head>
    <body>



<div  id="occupationsContainer">
<input name="occupation[]">
<input type="button"  id="addNewInput" value="add">
</div>

    </body>
    </html>

Thank you a lot for your help.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM