How to dynamically add form elements via JavaScript



Not all forms are meant to be static. Sometimes, you want to allow the users to add certain parts of the form as they need them. Here is a nice example of dynamically adding inputs to your form as users need them. In addition, an input limit has been implemented in the script and it is set to 3.

Demo
Entry 1



Here is the plain HTML for the form:

  1. <script src="/wp-includes/js/addInput.js" language="Javascript" type="text/javascript"></script>
  2. <form method="POST">
  3.      <div id="dynamicInput">
  4.           Entry 1<br><input type="text" name="myInputs[]">
  5.      </div>
  6.      <input type="button" value="Add another text input" onClick="addInput('dynamicInput');">
  7. </form>

When the user clicks on the Add another text input button, the addInput JavaScript function is executed and given the dynamicInput argument which is the name of the div that contains all our text inputs. Here is what our JavaScript function looks like:

  1. var counter = 1;
  2. var limit = 3;
  3. function addInput(divName){
  4.      if (counter == limit)  {
  5.           alert("You have reached the limit of adding " + counter + " inputs");
  6.      }
  7.      else {
  8.           var newdiv = document.createElement('div');
  9.           newdiv.innerHTML = "Entry " + (counter + 1) + " <br><input type='text' name='myInputs[]'>";
  10.           document.getElementById(divName).appendChild(newdiv);
  11.           counter++;
  12.      }
  13. }

There are a couple of global variables:

  • counter – Tracks the number inputs being added.
  • limit – The maximum number inputs allowed for the user to add. In this case, we are limiting the user to a maximum of 3 input texts that they can submit with the form.

The addInput JavaScript function expects a parameter, which in this case is the id of the div, to add the dynamic text inputs. Once executed, the function will first check to see if the maximum number of input texts have already been used. If so, an alert will be given stating that the limit has been reached.

If the limit has not been reached, then the else block of the code is executed. A new div element is created and the inner HTML is set with 2 things:

  • Entry # – The global variable, counter, keeps track of the current number of text inputs that are in the form.
  • The input text element – The name of these text inputs,myInputs[], is followed by square brackets to indicate that it is an array. This will be more important later on when the form is submitted using the POST method.

If the form gets submitted to a PHP file, you can easily access each input value for your myInputs array. Here is the PHP code for doing just that:

  1. $myInputs = $_POST["myInputs"];
  2. foreach ($myInputs as $eachInput) {
  3.      echo $eachInput . "<br>";
  4. }

This is just a sample code to echo all the text input values that were sent from the form. An array variable, $myInputsPHP, is initialized with the myInputs from the form. Then, the foreach loop will go through each value and print them out.

Here is another version of this script that adds different types of inputs such as text fields, radio buttons, checkboxes, and textareas. To simplify things, the limit functionality has been removed.

Demo
Let’s start adding some inputs of different types.



Here is the plain JavaScript code for the addAllInputs function. It accepts 2 arguments:

  • div id – This is the div id where all the dynamic inputs will be added to.
  • input type – This is the type of input that we want to add.
  1. var counterText = 0;
  2. var counterRadioButton = 0;
  3. var counterCheckBox = 0;
  4. var counterTextArea = 0;
  5. function addAllInputs(divName, inputType){
  6.      var newdiv = document.createElement('div');
  7.      switch(inputType) {
  8.           case 'text':
  9.                newdiv.innerHTML = "Entry " + (counterText + 1) + " <br><input type='text' name='myInputs[]'>";
  10.                counterText++;
  11.                break;
  12.           case 'radio':
  13.                newdiv.innerHTML = "Entry " + (counterRadioButton + 1) + " <br><input type='radio' name='myRadioButtons[]'>";
  14.                counterRadioButton++;
  15.                break;
  16.           case 'checkbox':
  17.                newdiv.innerHTML = "Entry " + (counterCheckBox + 1) + " <br><input type='checkbox' name='myCheckBoxes[]'>";
  18.                counterCheckBox++;
  19.                break;
  20.           case 'textarea':
  21. 	       newdiv.innerHTML = "Entry " + (counterTextArea + 1) + " <br><textarea name='myTextAreas[]'>type here...</textarea>";
  22.                counterTextArea++;
  23.                break;
  24.           }
  25.      document.getElementById(divName).appendChild(newdiv);
  26. }

If you found that my code was helpful in any way, shape, or form and would like to buy me a beer, please use the Donate button below =) Cheers!





Published by

Allen Liu

Building websites is a passion of mine. During the course of my work, I have created some snippets of code that I hope will prove useful to other developers.

128 thoughts on “How to dynamically add form elements via JavaScript”

  1. Hi Allen,

    Just read through your tutorial on dynamically adding form elements via javascript and found it to be extremely helpful. However, the “name” attribute has been deprecated in HTML5. How would you suggest changing the code in consideration of this?

    Thanks

    1. Yea, it’s been a long time since the tutorial was first written. I would recommend using the ‘class’ attribute instead of ‘name’. Also, if you have the option of using jQuery vs plain JavaScript, I would recommend that as well.

  2. Hi, I’m a computer science student working on a final project and this tutorial is EXACTLY what I need. However, when I use the code for HTML and Javascript you provided my initial form is there, but when I click the submit button a second for does not appear. I made sure to update the file path for the Javascript file addInput.js, but can’t figure out where I went wrong.
    Here’s my HTML code:

    Ingredient 1

    Here’s my Javascript:
    let counter = 1;
    let limit = 30;
    function addInput(divName){
    if (counter == limit) {
    alert(“You have reached the limit of adding ” + counter + ” inputs”);
    }
    else {
    let newdiv = document.createElement(‘div’);
    newdiv.innerHTML = “Ingredient ” + (counter + 1) + ‘ ‘;
    document.getElementById(divName).appendChild(newdiv);
    counter++;
    }
    }

    1. Hi,

      I would gladly help but I would need to see your HTML as well. If you can create a jsFiddle with all your code, that would be best. If you happen to have a link to the page with the issue, that would work as well.

      Allen

  3. This was a very nice tutorial. But please, I want to dynamically add a select element with options using javascript when the user clicks on “Add New” button. Can you give me some help, please?

  4. Nice Work, I just had problems integrating my existing code to your code. I’m trying to add a dynamic search text field that retrieves data from database through json. It only works with the first field, not to the ones I start adding.

    Any help will be appreciated, thanks.

    // search item dynamically
    $(document).ready(function(){
    $(“#search_results”).slideUp();
    $(“#button_find”).click(function(event){
    event.preventDefault();
    search_ajax_way();
    });
    $(“#search_query”).keyup(function(event){
    event.preventDefault();
    search_ajax_way();
    });

    });

    function search_ajax_way(){
    $(“#search_results”).show();
    var search_this=$(“#search_query”).val();
    $.post(“functions/search_items.php”, {searchit : search_this}, function(data){
    $(“#display_results”).html(data);
    $(‘#display_results’).show();

    })
    }
    // set_item : this function will be executed when we select an item
    function set_item(itemid, item) {
    // change input value
    $(‘#search_query’).val(item);
    $(‘#search_query_id’).val(itemid);
    // hide proposition list
    $(‘#display_results’).hide();

    }

    var counter = 1;
    var limit = 15;
    function addInput(divName){

    if (counter == limit) {
    alert(“You have reached the limit of adding ” + counter + ” inputs”);
    }
    else {
    var newdiv = document.createElement(‘div’);
    newdiv.innerHTML = “Item ” + (counter + 1) + ” “;
    document.getElementById(divName).appendChild(newdiv);
    counter++;
    }
    }

  5. Hi Jeremy,

    I suspect that you have some jQuery or JavaScript that initializes the nice looking file upload UI and it’s not running for any dynamically added elements. If you can you give me the snippet of jQuery/JavaScript code that does that, this should be an easy fix.

    Allen

      1. I took a look at the plugin you’re using and it looks like the initialization step looks something like this:

        $("#input-id").fileinput();

        According to this, you would need to tack on the following to your addInput() function.

        function addInput(divName){
             if (counter == limit)  {
                  alert("You have reached the limit of adding " + counter + " inputs");
             }
             else {
                  var newdiv = document.createElement('div');
                  newdiv.innerHTML = "<br><h5>Product " + (counter + 1) + "</h5> <div class='row'><section class='unit span6'>Name<br><input placeholder='Name of product' type='text' name='productName[]' required></section><section class='unit span6'>Price<br><input placeholder='Price of product' type='text' name='productPrice[]' required></section></div><br />Description<br><div class='textarea relative'><label class='icon-append' for='message'><i class='fa fa-align-left'></i></label><textarea placeholder='Describe the product' name='productDescription[]' title='Type the product description here!' required></textarea></div><br />Product Image<br>" + imageText;
                  document.getElementById(divName).appendChild(newdiv);
                  counter++;
             }
             $(".file").fileinput();
        }

        Note that this will re-initialize your existing file inputs so it’s not optimal. One way around this is to assign unique ID’s for your file inputs.

        var imageText = `<input id="somethingUnique" name="productImage[]" type="file" class="file" data-preview-file-type="text" required>`;
        function addInput(divName){
             if (counter == limit)  {
                  alert("You have reached the limit of adding " + counter + " inputs");
             }
             else {
                  var newdiv = document.createElement('div');
                  newdiv.innerHTML = "<br><h5>Product " + (counter + 1) + "</h5> <div class='row'><section class='unit span6'>Name<br><input placeholder='Name of product' type='text' name='productName[]' required></section><section class='unit span6'>Price<br><input placeholder='Price of product' type='text' name='productPrice[]' required></section></div><br />Description<br><div class='textarea relative'><label class='icon-append' for='message'><i class='fa fa-align-left'></i></label><textarea placeholder='Describe the product' name='productDescription[]' title='Type the product description here!' required></textarea></div><br />Product Image<br>" + imageText;
                  document.getElementById(divName).appendChild(newdiv);
                  counter++;
             }
             $("#somethingUnique").fileinput();
        }

        To automate it so that each input element gets a unique ID, you can append on the counter to the ID name and that will keep it unique. Currently, you are creating input elements with the same ID which is something you want to avoid. Here is an example of what would look like:

        var counter = 1;
        var limit = 20;
        var imageText = '<input id="productImage_' + counter + '" name="productImage[]" type="file" class="file" data-preview-file-type="text" required>';
        function addInput(divName){
             if (counter == limit)  {
                  alert("You have reached the limit of adding " + counter + " inputs");
             }
             else {
                  var newdiv = document.createElement('div');
                  newdiv.innerHTML = "<br><h5>Product " + (counter + 1) + "</h5> <div class='row'><section class='unit span6'>Name<br><input placeholder='Name of product' type='text' name='productName[]' required></section><section class='unit span6'>Price<br><input placeholder='Price of product' type='text' name='productPrice[]' required></section></div><br />Description<br><div class='textarea relative'><label class='icon-append' for='message'><i class='fa fa-align-left'></i></label><textarea placeholder='Describe the product' name='productDescription[]' title='Type the product description here!' required></textarea></div><br />Product Image<br>" + imageText;
                  document.getElementById(divName).appendChild(newdiv);
                  counter++;
             }
             $("#productImage_' + counter + '").fileinput();
        }

        I hope this leads you in the right direction.

        Allen

        1. I did exactly what you said, except replaced “productImage + counter” to “productImage + (counter + 1)”, and also changed the original form id to productImage_1.

          The CSS still doesn’t want to show up.

  6. Thanks a lot for this tutorial. I’m a computer science student and we have to make a website where a person can register and add multiple phone numbers. I have never used js before (this is my first year) so my old solution was to let the user seperate their phone numbers with commas but that’s not really a good solution! This post helped me get on the right track. The code is a lot simpler and easier to understand than most I’ve found so far, so I could actually understand it, alter it and add comments/explaination of how it works without really knowing js yet!

  7. Allen, thanks for this tutorial, it is the best I have seen yet online after days of searching. I have a question. I am looking to have multiple form fields. I can create the form, but when I go to submit, the foreach loop generates an error. I am not doing this part correctly. I appreciate your assistance!

    $myInputs = $_POST[“myInputs”];
    $myInputs2 = $_POST[“myInputs2”];
    $myInputs3 = $myInputs || $myInputs2;
    foreach ($myInputs3 as $eachInput) {
    echo $eachInput . “”;

    1. The code looks good on inspection. What error do you see? Are you sure $myinputs3 is an array? Is there a link to the page that you can share?

  8. Hi, It’s perfect sample and help.I want to thank you.
    If its possible can you give example how to get textarea data with vbscript asp? ” + FPL + “” Best regards.

    1. Sorry, I’m very familiar with VBScript. If you are working with ASP.NET, you should be able to use the JavaScript and HTML code as is.

      Allen

  9. Great help. But I see it can not be used to add a dropdown menu itself?
    I have two drop down menus int a form that provide options for two different kinds of specifications of a product item. I want to be able to have an “Add Item” option for users who want more than one product, but each with different specifications. So I basically need the “Add Item” button to generate two or more extra dropdown menus with the original data in them, for a new item. How can I do this?

    1. Hi Nita,

      You can have the extra dropdown menus “hidden” with the display attribute set to none. If a user pushes the “Add Item” button, you can simply change the CSS of the dropdown menus via JavaScript to make the visible.

      Allen

  10. Thanks, this puts me on the right track for another project that I’m planning. Can anyone show a simple example of how to display another textfield based on a checkbox being selected? An example would be to allow a visitor to add their cell phone number. If the checkbox is not clicked the Cell Phone field is not displayed on the form, if it is, the field is displayed. I’m actually planning to use this functinality where a visitor has multiple addresses but only the primary would be displayed if they only had one address.

    Thanks for any examples that can be provided.

Leave a Reply

Your email address will not be published. Required fields are marked *