skip to Main Content

I’m quite new to JS so was wondering what would be the best way to check status of multiple checkboxes, and then change content of several text boxes.
I have been able to kind of do this, but not without very much nesting if statements etc.

More specifically the checkboxes represent an "object" with a name, based of the status of the checkbox I want to add it or remove this name to one or more text boxes (some names are to be displayed only in one text area/box, but other must show up in several text areas/boxes.

checkboxes:

Name 1 X
Name 2 X
Name 3 X
Name 4 X
Name 5 X


Sign 1 Sign 2 Sign 3 Sign 4
Name 1
Name 1 Name 2 Name 2
Name 2 Name 4 Name 3
Name 5
———————- ——————– —————– —————-

What would be the best way to somehow store the values for the signs and loop thru all checkboxes to check if their active and then update the signs with correct info?

HTML:

<p class="myText"><input type="checkbox" id="idName1" name="idName1" onclick="updateSigns()">Name 1</p>

Been able to do it somehow with checking one by one using

let status = document.getElementById('someIDofCheckbox').checked;

by storing them in several variables, and "manually" check them, but this I know is the wrong way and also very cumbersome.

Hope the question made sense and someone is able to chime in some tips on this one.

The "signs"/boxes itself is only defines as:

<div class="content" id="on"><h3>Sign 1</h3><p id="idSign1"></p></div>

Updated javascript showing what I want to achieve – only with more boxes and more checkboxes:

let N1 = '';
let N2 = '';
let text1 = '';
let text2 = '';

function updateSigns(){

let status = document.getElementById('idName1').checked;
let status2 = document.getElementById('idName2').checked;

console.log(status);

if(status==true){

    N1 = 'Name 1n'
}
else if(status==false){

    N1 = '';
 }

 if (status2 ==true){
    N2 = 'Name 2n';
 }
 else if(status2==false){
    N2= '';
 }

 text1 = N1 + N2;
 text2 = N2;

document.getElementById('Sign1').innerText = text1;
document.getElementById('Sign2').innerText = text2;



}

2

Answers


  1. For this task, you need to have a proper data model as a source of which cells need to be updated.

    Here is an example of how this could be achieved. I’ve skipped table styling for simplicity. Also, I don’t generate thead/tbody for the same reason.

    Please let me know if this helps.

    const model = [
      ['Name 1', '', 'Name 2', ''],
      ['Name 2', 'Name 3', 'Name 3', 'Name 4'],
      ['Name 3', '', 'Name 3', 'Name 4'],    
    ];
    
    const getChecks = () => {
      const checksWrapper = document.querySelector('#checksWrapper');
      const checkInputs = checksWrapper.querySelectorAll('input');
      const checks = {};
      Array.from(checkInputs).forEach((el) => {
        checks[el.name] = el.checked;
      });
      return checks;
    };
    
    const updateTable = () => {
      const checks = getChecks();
    
      const tableWrapper = document.querySelector('#tableWrapper');
      tableWrapper.innerHTML = '';
    
      const table = document.createElement('table');
      tableWrapper.appendChild(table);
    
      const header = document.createElement('tr');
      table.appendChild(header);
      for (let colIndex=0; colIndex<model[0].length; colIndex ++) {
        const cell = document.createElement('td');
        header.appendChild(cell);
        cell.innerText = `Sign ${colIndex + 1}`;
      }
     
      for (let rowIndex=0; rowIndex<model.length; rowIndex ++) {
        const rowElement = document.createElement('tr');
        table.appendChild(rowElement);
        const row = model[rowIndex];
        for (let colIndex=0; colIndex<row.length; colIndex ++) {
          const cell = document.createElement('td');
          rowElement.appendChild(cell);
          cell.innerText = checks[row[colIndex]] ? row[colIndex] : '';
        }
      }
    };
    
    updateTable();
    table {
      background-color: #e0e0e0;
      width: 100%;
    }
    
    tr {
      height: 20px;
    }
    
    td {
      background-color: #ffffff;
      min-width: 100px;
    }
    <html>
      <body>
        <div id="checksWrapper">
          <label><input type="checkbox" onclick="updateTable()" name="Name 1">Name 1</label>
          <label><input type="checkbox" onclick="updateTable()" name="Name 2">Name 2</label>
          <label><input type="checkbox" onclick="updateTable()" name="Name 3">Name 3</label>
        </div>
        <div id="tableWrapper">
        </div>
      </body>
    </html>
    Login or Signup to reply.
  2. I’m not 100% sure that I understand the question, but hopefully this helps.

    You can use querySelectorAll to select all the checked checkboxes; in the example below this looks like:

    document.querySelectorAll('#checkboxes_container input:checked')
    

    Structuring your data can make building the content text easier as you can loop through each value and compare them with the list of checked checkboxes.

    const sign_items = {
      1: ['', 'Name 1', 'Name 2', 'Name 5'],
      2: ['', 'Name 2', 'Name 4', ''],
      3: ['Name 1', 'Name 2', 'Name 3', ''],
    };
    
    const names_to_text = (sign_names, checked_names) =>
      sign_names
        .map( (sign_name) => checked_names.includes(sign_name) ? sign_name : '' )
        .join("n");
    
    const update_signs = () => {
      const checked_names = Array.from(
        document.querySelectorAll('#checkboxes_container input:checked')
      ).map( (input) => input.dataset.text );
      
      for(const [sign_num, names] of Object.entries(sign_items)) {
        document.getElementById('sign_content_' + sign_num).innerText =
          names_to_text(names, checked_names);
      }
    };
    
    document.getElementById('checkboxes_container').addEventListener('click', (event) => {
      if(event.target.tagName.toLowerCase() === 'input')
        update_signs();
    });
    
    update_signs();
    #content {
      display: flex;
      gap: 10px;
      width: 100%;
    }
    
    .column {
      min-width: 100px;
    }
    <div id="checkboxes_container">
      <label><input type="checkbox" data-text="Name 1" />Name 1</label>
      <label><input type="checkbox" data-text="Name 2" />Name 2</label>
      <label><input type="checkbox" data-text="Name 3" />Name 3</label>
      <label><input type="checkbox" data-text="Name 4" />Name 4</label>
      <label><input type="checkbox" data-text="Name 5" />Name 5</label>
    </div>
    
    <div id="content">
      <div class="column">
        <h3>Sign 1</h3>
        <p class="sign_content" id="sign_content_1"></p>
      </div>
      <div class="column">
        <h3>Sign 2</h3>
        <p class="sign_content" id="sign_content_2"></p>
      </div>
      <div class="column">
        <h3>Sign 3</h3>
        <p class="sign_content" id="sign_content_3"></p>
      </div>
    </div>
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search