X3minater
X3minater

Reputation: 99

New input on button click

really noob question, but can someone tell me what's wrong with this code?

I'm trying to create, dynamically on button click, new input boxes with a new button on the side.

I want the new input boxes and buttons to have distinct IDs so I can delete them after.

Bonus question: How would I go about deleting a specific input box and button?

var counter = 1;

function addInput(){
  var newdiv = document.createElement('div');
  newdiv.id = dynamicInput[counter];
  newdiv.innerHTML = "Entry " + (counter + 1) + " <br><input type='text' name='myInputs[]'> <input type='button' value='-' onClick='removeInput("+dynamicInput[counter]+");'>";
  document.getElementById('formulario').appendChild(newdiv);
  counter++;
}
<form method="POST" id="formulario">
  <div id="dynamicInput[0]">
    Entry 1<br><input type="text" name="myInputs[]"> 
    <input type="button" value="+" onClick="addInput();">
  </div>
</form>

Upvotes: 1

Views: 5470

Answers (4)

zer00ne
zer00ne

Reputation: 43880

Instead of creating elements from the start, use what you already have by cloning the first group of elements. Details are commented in Snippet.

SNIPPET

/* The original dynamic input 
|| is hiding it's remove button
|| so the first input never gets 
|| deleted
*/

#dynInp0 input:last-of-type {
  display: none;
}
input {
  font: inherit;
}
[type='text'] {
  width: 20ch;
  line-height: 1.1;
}
[type='button'] {
  width: 2.5ch;
  height: 2.7ex;
}
<html>

<head>
  <script>
    var counter = 0;

    function addInput() {
        var form = document.getElementById('formulario');
        // Increment counter
        counter++;
        // Reference dynamic input
        var template = document.getElementById('dynInp0');
        // Clone dynamic input
        var clone = template.cloneNode(true);
        /* Reassign clone id to the string "dynInp"...
        ||...concatenated to the current value of counter
        */
        clone.id = "dynInp" + counter;
        // Reference the first child of clone (<label>)
        var tag = clone.children[0];
        /* Change tag's text to the string "Entry "...
        ||...concatenated to the current value of counter
        */
        tag.textContent = "Entry " + counter;
        // Reference the 5th child of dynInp (<input>)
        var rem = clone.children[4];
        // Change button display to `inline-block'
        rem.style.display = 'inline-block';
        // Append clone to <form>
        form.appendChild(clone);
      }
      /* Pass the obj ele...
      ||...Reference <form>...
      ||...Reference the parent of ele...
      ||...Remove parent from <form>
      */

    function removeInput(ele) {
      var form = document.getElementById('formulario');
      var parent = ele.parentNode;
      var removed = form.removeChild(parent);
    }
  </script>
</head>

<body>
  <form method="POST" id="formulario">
    <div id="dynInp0">
      <label>Entry 0</label>
      <br>
      <input type="text" name="myInputs[]">
      <input type="button" value="+" onclick="addInput();">
      <input type='button' value="-" onclick='removeInput(this);'>
    </div>
  </form>
</body>

</html>

Upvotes: 1

Nicholas Smith
Nicholas Smith

Reputation: 712

There is an error in your code:

Uncaught ReferenceError: dynamicInput is not defined

You need to define dynamicInput first.

<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script>
var counter = 1;
var dynamicInput = [];

function addInput(){
    var newdiv = document.createElement('div');
    newdiv.id = dynamicInput[counter];
    newdiv.innerHTML = "<section onclick='$(this).remove();'>Entry " + (counter + 1) + " <br><input type='text' name='myInputs[]'> <input type='button' value='-'></section>";

    document.getElementById('formulario').appendChild(newdiv);
    counter++;
}
</script>
</head>
<body>
<form method="POST" id="formulario">
     <div id="dynamicInput[0]">
        Entry 1<br><input type="text" name="myInputs[]"> 
        <input type="button" value="+" onClick="addInput();">
    </div>
</form>
</body>
</html>
To delete an input, simply add a section with an event handler with $(this).remove(). You will require jQuery to do this. The snippet above contains the following already.

Upvotes: 1

Nikolay Ermakov
Nikolay Ermakov

Reputation: 5061

You don't need a counter and ids at all if adding/removing is all you want. You can get relevant inputs using this passed to the methods.

<html>
  <head>
    <script>

      function addInput(){
        var newdiv = document.createElement('div');
        //newdiv.id = dynamicInput[counter];
        newdiv.innerHTML = "Entry <br><input type='text' name='myInputs[]'> <input type='button' value='-' onClick='removeInput(this);'>";
        document.getElementById('formulario').appendChild(newdiv);
      }

      function removeInput(btn){
          btn.parentNode.remove();
      }

    </script>
  </head>
  <body>
    <form method="POST" id="formulario">
      <div>
        Entry 1<br><input type="text" name="myInputs[]"> 
        <input type="button" value="+" onClick="addInput();">
      </div>
    </form>
  </body>
</html>

Upvotes: 3

Alexandre Neukirchen
Alexandre Neukirchen

Reputation: 2783

Additionally, you can also delete the created element:

<html>
<head>
<script>
var counter = 1;
var dynamicInput = [];

function addInput(){
    var newdiv = document.createElement('div');
    newdiv.id = dynamicInput[counter];
    newdiv.innerHTML = "Entry " + (counter + 1) + " <br><input type='text' name='myInputs[]'> <input type='button' value='-' onClick='removeInput("+dynamicInput[counter]+");'>";
    document.getElementById('formulario').appendChild(newdiv);
    counter++;
}
  
  function removeInput(id){
    var elem = document.getElementById(id);
    return elem.parentNode.removeChild(elem);
  }
</script>
</head>
<body>
<form method="POST" id="formulario">
     <div id="dynamicInput[0]">
        Entry 1<br><input type="text" name="myInputs[]"> 
        <input type="button" value="+" onClick="addInput();">
    </div>
</form>
</body>
</html>

Upvotes: 4

Related Questions