-3

I have a form where I'd like to add new input fields, and I'm sure I almost got it but something's not working because the name attribute is not auto incrementing.

<button onclick="afunction()">Insert New Text Field</button>
<script>
function afunction() {
    var x = document.createElement("INPUT");
    x.setAttribute("type", "text");
    x.setAttribute("value", "something cool");
    for (i = 0; i < 12; i++) {
    x.setAttribute("name","input"+i);
}
document.body.appendChild(x);
}
</script>

Thank you for your valuable help.

Samuel Ramzan
  • 1,770
  • 1
  • 15
  • 24

2 Answers2

2

Your for-loop looping from i = 0 to 11 does not make sense. With each loop iteration, you just override the previously set name attribute of the same element x and finally end up with "input" + 11 as the name.

You need to move the declaration of your counter variable (I called it numInputs) outside your function and only increment it by one for each function call, e. g. as follows:

var numInputs = 0;

function addInput() {
  var input = document.createElement("input");
  input.setAttribute("type", "text");
  input.setAttribute("value", "something cool");
  input.setAttribute("name", "input" + numInputs);
  document.body.appendChild(input);
  numInputs++;
  
  // Debug output:
  console.log(document.body.querySelectorAll('input[name^=input]'));
}
<button onclick="addInput()">Insert New Text Field</button>

If you feel more confident in your Javascript programming skills, you can encapsulate your counter variable numInputs and the addInput function as a closure within an Immediately-Invoked Function Expression:

const addInput = (function() {
  var numInputs = 0;
  return function() {
    var input = document.createElement("input");
    input.setAttribute("type", "text");
    input.setAttribute("value", "something cool");
    input.setAttribute("name", "input" + numInputs);
    document.body.appendChild(input);
    numInputs++;

    // Debug output:
    console.log(document.body.querySelectorAll('input[name^=input]'));
  }
})();
<button onclick="addInput()">Insert New Text Field</button>
Community
  • 1
  • 1
le_m
  • 19,302
  • 9
  • 64
  • 74
1

The variable i is always going to evaluate to 11. The for loop will run every time you run that function, and will set the name attribute of your input element to "name0", "name1", "name2", "name3", "name4", "name5", "name6", "name7", "name8", "name9", "name10", and finally... "name11". What you probably want to do is set up a closure to store the value, unless you want to use another attribute on an html element to store the value. My solution is pretty similar to MDN's information on closures here: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Closures

Here's what I came up with. Probably more efficient to set a value on an html element and increment that...

<button onclick="afunction()">Insert New Text Field</button>
<script>
function counter() {
  var i = 0;
  return {
    increment: function () {
      i++;
    },
    value: function () {
      return i;
    }
  };
}
var i = counter();
function afunction() {
    var x = document.createElement("INPUT");
    x.setAttribute("type", "text");
    x.setAttribute("value", "something cool");

    i.increment();
    x.setAttribute("name","input"+i.value());
    document.body.appendChild(x);
  }

</script>

http://codepen.io/IAMZERG/pen/VjLJwO

IAMZERG
  • 100
  • 9
  • What is the advantage of using your counter-object with 'private' variable `i` instead of just a Number, i. e. `var i = 0;`? – le_m Jun 06 '16 at 03:50
  • None whatsoever in this case. I created a slightly more coomplicated example to showcase where it might come in handy: http://codepen.io/IAMZERG/pen/qNdzdg – IAMZERG Jun 06 '16 at 04:21