0

I have a select box with a few dropdown options. Under each option there will be a checklist and total (each checklist item has a value). I need to accomplish this using pure javascript.

My problem is I don't know how to make each checklist specific to its dropdown item, and to reset the checkbox values after a user clicks a new dropdown option. I've tried calling the totalIt function in the display function but I can't get it to work.

Fiddle

My HTML is:

<div>
  <select id="store">
    <option value="A">Location A</option>
    <option value="B">Location B</option>
    <option value="C">Location C</option>
  </select>
</div>

<div class="box A">
  Location A<br>
  <input name="product" value="20" type="checkbox" onclick="totalIt()" /> 20%<br>
  <input name="product" value="15" type="checkbox" onclick="totalIt()" /> 15%<br>
  Total:
  <input value="0" readonly="readonly" type="text" name="total" />
</div>

<div class="box B">
  Location B
  <br>
  <input name="product" value="20" type="checkbox" onclick="totalIt()" /> 20%<br>
  <input name="product" value="15" type="checkbox" onclick="totalIt()" /> 15%<br>
  Total:
  <input value="0" readonly="readonly" type="text" name="total" />
</div>

<div class="box C">
  Location C
  <br>
  <input name="product" value="20" type="checkbox" onclick="totalIt()" /> 20%<br>
  <input name="product" value="15" type="checkbox" onclick="totalIt()" /> 15%<br>
  Total:
  <input value="0" readonly="readonly" type="text" name="total" />
</div>

CSS:

.hide {
  display: none;
}

JS:

document.querySelector("select#store").addEventListener("change", () => {
  display(event.target.value);
});

const boxs = document.querySelectorAll("div.box");
 
// Select box show/hide div
function display(value) {
  for (const box of boxs) {
    if (box.classList.contains(value)) {
      box.classList.remove("hide");
    } else {
      box.classList.add("hide");
    }
  }
}
display("A");
   
// Total the values of the checkboxes
function totalIt() {
  var input = document.getElementsByName("product");
  var total = 0;
  for (var i = 0; i < input.length; i++) {
    if (input[i].checked) {
      total += parseFloat(input[i].value);
    }
  }
  document.getElementsByName("total")[0].value = total + "%";
}
clive
  • 51
  • 6

3 Answers3

1

Try to use the selected box children property. So that only those elements under the box would be updated. You are almost there I just had to tweak the code just a little.

HTML:

  <div>
    <select id="store">
      <option value="A">Location A</option>
      <option value="B">Location B</option>
      <option value="C">Location C</option>
    </select>
  </div>
  
  <div class="box A">
    Location A <br>
    Select your items:
    <br>
    <input name="proPercent1" value="20" type="checkbox" onclick="totalIt()"/> 20%<br>
    <input name="proPercent2" value="15" type="checkbox" onclick="totalIt()"/> 15%<br>
    Total:<br>
    <input value="0" readonly="readonly" type="text" name="total" />
  </div>
  
  <div class="box B">
    Location B <br>
    Select your items:
    <br>
    <input name="proPercent1" value="20" type="checkbox" onclick="totalIt()"/> 20%<br>
    <input name="proPercent2" value="15" type="checkbox" onclick="totalIt()"/> 15%<br>
    Total:<br>
    <input value="0" readonly="readonly" type="text" name="total" />
  </div>
  
  <div class="box C">
    Location C <br>
    Select your items:
    <br>
    <input name="proPercent1" value="20" type="checkbox" onclick="totalIt()" name="percentage1"/> 20%<br>
    <input name="proPercent2" value="15" type="checkbox" onclick="totalIt()"/> 15%<br>
    Total:<br>
    <input value="0" readonly="readonly" type="text" name="total" />
  </div>

JS:

    document.querySelector("select#store").addEventListener("change", () => {
        display(event.target.value);
    });

    const boxs = document.querySelectorAll("div.box");
    let selectedBox = "";

    function display(value) {
        for (const box of boxs) {
            if (box.classList.contains(value)) {
            box.classList.remove("hide");
            selectedBox = box;
            } else {
            box.classList.add("hide");
            }
        }
    }
    display("A");

    // Total the values of the checkboxes
    function totalIt() {
        let total = 0;
        if(selectedBox.children.proPercent1.checked) total = total + parseInt(selectedBox.children.proPercent1.value)
        if(selectedBox.children.proPercent2.checked) total = total + parseInt(selectedBox.children.proPercent2.value)
        selectedBox.children.total.value = `${total} %`;
    }

Hopefully this helps

Dharman
  • 30,962
  • 25
  • 85
  • 135
Chait
  • 511
  • 7
  • 15
1

Hi, I get solution to your problem...

document.querySelector("select#store").addEventListener("change", () => {
  display(event.target.value);
});

const boxs = document.querySelectorAll("div.box");
 
// Select box show/hide div
function display(value) {
  for (const box of boxs) {
    if (box.classList.contains(value)) {
      box.classList.remove("hide");
    } else {
      box.classList.add("hide");
    }
  }
}
display("A");
   
// Total the values of the checkboxes
function totalIt(Group) {
  let input = document.querySelectorAll(`.${Group} [name=product]`),
      total = 0,
      totalInput = document.querySelector(`.${Group} [name=total]`)
  input.forEach(input => {
    if(input.checked) total += parseFloat(input.value);
    totalInput.value = total + "%"
  })
}
.hide {
  display: none;
}
.box {
  margin-top:30px;
}
        <div>
            <select id="store">
              <option value="A">Location A</option>
              <option value="B">Location B</option>
              <option value="C">Location C</option>
            </select>
          </div>
          
          <div class="box A">
            Location A<br>
            <input name="product" value="20" type="checkbox" onclick="totalIt('A')" /> 20%<br>
            <input name="product" value="15" type="checkbox" onclick="totalIt('A')" /> 15%<br>
            Total:
            <input value="0" readonly="readonly" type="text" name="total" />
          </div>
          
          <div class="box B">
            Location B
            <br>
            <input name="product" value="20" type="checkbox" onclick="totalIt('B')" /> 20%<br>
            <input name="product" value="15" type="checkbox" onclick="totalIt('B')" /> 15%<br>
            Total:
            <input value="0" readonly="readonly" type="text" name="total" />
          </div>
          
          <div class="box C">
            Location C
            <br>
            <input name="product" value="20" type="checkbox" onclick="totalIt('C')" /> 20%<br>
            <input name="product" value="15" type="checkbox" onclick="totalIt('C')" /> 15%<br>
            Total:
            <input value="0" readonly="readonly" type="text" name="total" />
          </div>
  1. I Convert for loop to forEach array loop
  2. I Change the selector from getElementsByNames to querySelector and querySelectorAll
  3. I Add argument to the function represent the Group
  4. I Noticed that you add class for each Group represent Name
  5. I Use this to make input selector and totalInput selector dedicated for each group... Like document.querySelectorAll(.a [name=product])
  6. Finally I call function and type name group in html
0

To uncheck a checkbox you set the element.checked value to false, (more here Check/Uncheck checkbox with JavaScript)

const allCheckboxes = document.querySelectorAll('input[type="checkbox"]');
function display (value) {
    allCheckboxes.forEach(element => element.checked = false);
    // your code
    ...
}
savageGoat
  • 1,389
  • 1
  • 3
  • 10