1

I'm trying to check if all the input fields are filled in this form, the inputs are created based on the number of players, so I dynamically created them in JavaScript, how can I do that ? Here is what I tried

const x = localStorage.getItem('playersNum');

for (let i = 0; i < x; i++) {

    const newInput = document.createElement("INPUT");
    newInput.setAttribute("type", "text");
    newInput.setAttribute("class", "form-control");
    newInput.setAttribute("id", `player${i}`);
    newInput.setAttribute("placeholder", "Player's Name");
    const parentDiv = document.getElementById('player-list');

    parentDiv.appendChild(newInput);

    const input = document.getElementById(`player${i}`);
    const btn = document.getElementById('startGame');
    btn.addEventListener('click', function() {
        if (input === "") {
            alert('Please fill in the players names');
        }
    });

}
Moe G
  • 27
  • 3

2 Answers2

3

You can try the following way:

const parentDiv = document.getElementById('player-list');
for (let i = 0; i < 2; i++) {
  const newInput = document.createElement("INPUT");
  newInput.setAttribute("type", "text");
  newInput.setAttribute("class", "form-control");
  newInput.setAttribute("id", `player${i}`);
  newInput.setAttribute("placeholder", "Player's Name");

  parentDiv.appendChild(newInput);
}

//get all input elements of type text and starting id with player
const input = document.querySelectorAll("[type='text'][id^='player']");
const btn = document.getElementById('startGame');
btn.addEventListener('click', function() {
  //reset border style of all input elements
  [...input].forEach(el => el.style.border = '');
  //get all empty input elements
  let empty = [...input].filter(el => el.value.trim() == "");
  //check length
  if (empty.length) {
    //show alert
    alert('Please fill in the players names');
    //set border style to empty input elements
    empty.forEach(el => el.style.border = '1px solid red');
  }
});
<button id="startGame">Start Game</button>
<div id="player-list"></div>
Mamun
  • 66,969
  • 9
  • 47
  • 59
2

You should check if the inputs are empty and attach an event listener to the start game button only after you've created them: this means after the for loop.

As an improvement you could add a required attribute on the inputs and check in CSS if they are invalid (using the :invalid pseudoclass)

const x = 3; 

const parentDiv = document.getElementById('player-list');
const btn = document.getElementById('startGame');

let players;

for (let i = 0; i < x; i++) {
    const newInput = document.createElement("input");
    newInput.setAttribute("type", "text");
    newInput.setAttribute("required", "required");
    newInput.setAttribute("class", "form-control");
    newInput.setAttribute("id", `player${i}`);
    newInput.setAttribute("placeholder", "Player's Name");
    parentDiv.appendChild(newInput);
}

/*
 * Get all the inputs you have just injected 
 */
players = [...document.querySelectorAll('.form-control')];

/*
 * Check if there are some inputs not filled
 */ 
btn.addEventListener('click', function() {
  if (players.some((p) => p.value === '')) {
      alert('Please fill in ALL the players names');
  }
  else {
     alert('Ok');
  }
});
input {
   display: block;
   margin: 1rem;
   border: 1px #ccc solid;
   padding: .25rem;
}

input:invalid {
 outline: 1px #aa0020 solid;
 outline-offset: 1px;
}
<div id="player-list"></div>

<button id="startGame">Start Game</button>
Fabrizio Calderan
  • 120,726
  • 26
  • 164
  • 177