1

I basically have an input of type number

<input type="number" id="no_pi" name="" onkeyup="des()">
<div id="extract"></div>

and function

function des() {
    var ext = document.getElementById('extract');
    var va = Number(document.getElementById('no_pi').value);
    for (var i = 0; i = va; i++) {
        ext.innerHTML = "<input type='number' name='' class='form-control'><div class='input-group-text'>cm</div>";
}
}

I just want to instantly generate x number of inputs in div based on user input. When the user input any number, the page just crashes down. I think the page is going in infinite loop, but I think it is not the case.

Any idea how to achieve this

Bryan Christy
  • 45
  • 1
  • 5

3 Answers3

1

Your key issue is how you're using your loop. i = va isn't going to accomplish what you want. It should be a check that the index in the iteration is less than the number represented by the value in your input. It should be i < va.

The other issue is that you're not adding to the HTML, just ensuring that the HTML is just one input.

I've adjusted the code in your question to remove the inline JS and use addEventListener instead, and also to use an array to store the HTML built from the loop which can then be applied to the extract element.

// Cache the elements outside of the loop
// and attach a change listener to the noPi element
const extract = document.getElementById('extract');
const noPi = document.getElementById('no_pi');
noPi.addEventListener('change', des, false);

function des() {

  const limit = noPi.value;

  // Check that we haven't gone into
  // negative numbers
  if (limit >= 0) {

    // Create an array
    const html = [];

    // Loop, pushing HTML into the array, until 
    // we've reached the limit set by the value in noPi 
    for (let i = 0; i < limit; i++) {
      html.push('<input type="number" class="form-control"><div class="input-group-text">cm</div>');
    }

    // `join` up the array, and add the HTML
    // string to the extract element
    extract.innerHTML = html.join('');

  }

}
<input type="number" id="no_pi" />
<div id="extract"></div>

Additional information

Andy
  • 61,948
  • 13
  • 68
  • 95
1

There's several errors :

  • In your loop : i = va (this is why it crashes)
  • You erase the content of the div ext each time you iterate, instead of adding content
  • By listening on keyup event, you add some content on each key hit. Finally if the user submit 12, it will generate 1 + 12 elements. You should pass the value using a form (by doing this you can also add easily the value control in the input element).
  • As perfectly mentionned by @Andy in the comments, innerHTML += is a very bad idea. You should generate your elements using document.createElement or insertAdjacentHTML.

Some advices :

  • Use an event listener instead of the onkeyup attribute
  • Avoid this kind of variable names, be more explicit
  • Use const and let instead of var

Here's a version which fixes all that issues :

document.getElementById('elementsNumberForm').addEventListener('submit', event => {
    event.preventDefault();
    const targetElement = document.getElementById('extract');
    const inputValue    = document.getElementById('no_pi').value;
    for (let i = 0; i < inputValue; i++) {
       targetElement.insertAdjacentHTML('beforeEnd', '<input type="number" name="" class="form-control" /><div class="input-group-text">cm</div>');
    }
});
<form id="elementsNumberForm">
    <input type="number" id="no_pi" min="1" />
    <input type="submit" />
</form>
<div id="extract"></div>
Joulss
  • 1,040
  • 1
  • 14
  • 26
0

I see that you want to use an input field to insert the number of inputs to create. I see a better way to start learning insert the number of inputs with a prompt, and then scale the project.

You can start like this: (hope it make sense to you)

<div style="height: 300px; background-color: #ccc;" class="container"></div>

we have this div that is going to be filled with the inputs

Then we have the script:

    const container = document.querySelector('.container');
    const runTimes = prompt("How many inputs wnat to create?");
    
    for(let i = 0; i < runTimes; i++){
        let newInput = document.createElement('input');
        newInput.innerHTML = "<input type='number' name='' class='form-control'>";
        container.appendChild(newInput);
    }

In the for loop, we create the element input, then with the .innerHTML we add the HTML we want. to end the loop, we need to append the created input element to the div we have.

hope it makes sense to you, :)

when you get the idea with the prompt , I´ve done this project more pro jaja.

<div style="height: 300px; background-color: #ccc;" class="container"></div>
<input type="text" class="numberTimes" onkeyup="getValue()">

we add an event listener to the input with the function getValuue, and the script like this:

const container = document.querySelector('.container');

    function getValue(){
        let runTimes = document.querySelector('.numberTimes').value;
        document.querySelector('.numberTimes').value= "";
        for(let i = 0; i < runTimes; i++){
            let newInput = document.createElement('input');
            newInput.innerHTML = "<input type='number' name='' class='form-control'>";
            container.appendChild(newInput);
        }
        
    }

This line document.querySelector('.numberTimes').value= ""; is to reset the input field. So whenever insert a value on the input it creates that number of inputs in the container and cleans the input field :)

zero0
  • 23
  • 1
  • 7