Sara Ree
Sara Ree

Reputation: 3543

Generate check boxes based on array elements then populate another array based on checked check boxes

Let's say we have an empty array that we want to populate it based on checked checkboxes :

let selected = [];

And another array of some person names:

let names = ['Joe', 'Mike', 'Sara', 'Jack'];

I want to generate checkboxes for each of the name's elements first, then I want to add each checked element to the selected array.

I can do this with drop-downs (code below) but I have no idea how this could be done with checkboxes:

let dropDown = document.getElementById('names');
let selected = [];
let names = ['Joe', 'Mike', 'Sara', 'Jack'];

// Loop through each of the voices.
names.forEach(function(e, i) {
  // Create a new option element.
  var option = document.createElement('option');

  // Set the options value and text.
  option.value = names[i];
  option.innerHTML = names[i];

  // Add the option to the voice selector.
  dropDown.appendChild(option);
});

// 3 seconds to select the item
setTimeout(function() {

  if (dropDown.value) {
    selected.push(dropDown.value)
  }

  console.log(selected)

}, 3000)
<div class="option">

  <label for="voice">US Pronunciation:</label>
  <select name="voice" id="names"></select>

</div>

Upvotes: 1

Views: 70

Answers (2)

Ivan
Ivan

Reputation: 40638

You can create a div element containing an input and a label for each element of the array. Each one of these elements needs to be appended to an existing parent element option. You can achieve this by writing down the actual HTML inside back-quotes. Then create an empty element with document.createElement. Using the innerHTML property you can fill this element with the HTML you wrote. Finally append it like you did using appendChild:

  const html = `
    <div>
      <input type="checkbox" id="${name}" name="${name}">
      <label for="${name}">${name}</label>
    </div>
  `.trim();

  const wrapper = document.createElement('div');
  wrapper.innerHTML = html;

  const element = option.appendChild(wrapper.firstChild);

Instead of using forEach to loop through your array, I would use map which allows us to create an array of input elements on the go. It's the exact same as using a forEach... the only difference is you need to return an element in your callback function:

const checkboxes = names.map(function(name) {

  const html = `
    <div>
      <input type="checkbox" id="${name}" name="${name}">
      <label for="${name}">${name}</label>
    </div>
  `.trim();

  const wrapper = document.createElement('div');
  wrapper.innerHTML = html;

  const element = option.appendChild(wrapper.firstChild);

  return element.querySelector('input');

});

So now we have an array called checkboxes which holds four input elements corresponding to our four names contained in the initial names array.

Whenever you need to know the checkboxes that are checked you can filter them out and get the names of the remaining ones. We'll do this using filter and another map:

checkboxes.filter(checkbox => checkbox.checked)
          .map(checkbox => checkbox.name);

Here's the full code:

const option = document.querySelector('.option');
const names = ['Joe', 'Mike', 'Sara', 'Jack'];

const checkboxes = names.map(function(name) {

  const html = `
    <div>
      <input type="checkbox" id="${name}" name="${name}">
      <label for="${name}">${name}</label>
    </div>
  `.trim();

  const wrapper = document.createElement('div');
  wrapper.innerHTML = html;

  const element = option.appendChild(wrapper.firstChild);

  return element.querySelector('input');

});

setTimeout(function() {

  const selected = checkboxes.filter(checkbox => checkbox.checked);

  console.log(selected.map(checkbox => checkbox.name));

}, 3000)
<div class="option">
</div>

Upvotes: 1

Matt Oestreich
Matt Oestreich

Reputation: 8528

You'll have to add an onClick event handler for the checkboxes and add them to the select that way.. Something like this should get you started:

let dropDown = document.getElementById('names');
let container = document.getElementById('container');
let selected = [];
let names = ['Joe', 'Mike', 'Sara', 'Jack'];

// Loop through each of the voices.
names.forEach(function(e, i) {
  let html = `
    <input onClick="handleCheck('container', 'names')" type="checkbox" name="checkbox" id="${i}_${e}" value="${e}">
    <label for="${i}_${e}">${e}</label>
  `;
  container.innerHTML += html;
});

function handleCheck(containerElementId, inputElementId) {
  let containerElement = document.getElementById(containerElementId);
  let select = document.getElementById(inputElementId);
  select.innerHTML = "";
  selected = [];
  containerElement.querySelectorAll('input[type="checkbox"]').forEach(el => {
    if(el.checked) {
      select.innerHTML += `<option value="${el.value}">${el.value}</option>`;
      selected.push(el.value);
    }
  })
  console.log("selected", selected);
}
<div class="option" id="container">

  <label for="voice">US Pronunciation:</label>
  <select name="voice" id="names"></select>

</div>

Upvotes: 2

Related Questions