Stone
Stone

Reputation: 31

Event listeners for both radio buttons and text input

I have a group of radio buttons and a text input field:

<div>
      <input type="radio" value="0.1" id="radioOne"   name="discount"  />
      <label for="radioOne" class="radio">10%</label>
</div>
<div>
      <input type="radio" value="0.2" id="radioTwo"   name="discount" />
      <label for="radioTwo" class="radio">20%</label>
</div>
<div>
      <input type="radio" value="0.3" id="radioThree"  name="discount" checked />
      <label for="radioThree" class="radio">30%</label>
</div>

<input type="number" name="price" id="priceInput" placeholder="Price">

<p id="resultToast"> </p>

And I wanna the result of final price calculated by Price * Discount and updating the <p id="resultToast"> </p>. So I did

const radios = document.querySelector('input[name="discount"]:checked');
const toast = document.querySelector('#resultToast');
const priceIn = document.querySelector("#priceInput");

if (radios) {
  document.querySelectorAll('input[name="discount"]').forEach((elem) => {
    elem.addEventListener("change", function(event) {
       radios.value = event.target.value;
       console.log(radios.value);
        if(priceIn){
          toast.textContent = 'final price:  ' + radios.value * priceIn.value;
        }
    });
  });
}

if(priceIn){
  priceIn.addEventListener('input', updateValue);
}

function updateValue(e) {
  toast.textContent = 'final price:  ' + e.target.value * radios.value;
}

From the console, the radios.value not updated correctly after clicking the radio buttons. What I did wrong?

Upvotes: 0

Views: 163

Answers (2)

Carsten Massmann
Carsten Massmann

Reputation: 28196

You are referring to a constant you defined at the beginning of your script. This will always give you the same radio button value (the one being checked at the beginning). Do something like

let discount=document.querySelector("input[name=discount]:checked").value

within your event handler function to get the current value of the radio button group.

You could also declutter(=shorten) your code a bit and make it reusable for multiple input sections that way, see below:

function qs(sel,el){return (el||document).querySelector(sel);}
function makeInteractive(frmsel){
  const frm=qs(frmsel),
        prc=qs("[name=price]",frm),
        res=qs(".result",frm);
  frm.onchange=calc;
  frm.oninput= calc;
  function calc(){
    res.textContent=
      (prc.value * qs("[type=radio]:checked",frm).value)
      .toFixed(2);    
  }
}

makeInteractive("#frm1");
makeInteractive("#frm2");            
<form id="frm1">
the first item ...
<div>
   <label><input type="radio" value="0.1" name="discount"/>10%</label>
</div>
<div>
   <label><input type="radio" value="0.2" name="discount"/>20%</label>
</div>
<div>
   <label><input type="radio" value="0.3" name="discount" checked/>30%</label>
</div>

<input type="number" name="price" id="priceInput" placeholder="Price">

<p id="resultToast" class="result"> </p>
</form>

<form id="frm2">
the second item ...
<div>
   <label><input type="radio" value="0.1" name="discount"/>10%</label>
</div>
<div>
   <label><input type="radio" value="0.2" name="discount"/>20%</label>
</div>
<div>
   <label><input type="radio" value="0.3" name="discount" checked/>30%</label>
</div>
<input type="number" name="price" id="priceInput" placeholder="Price">

<p id="resultToast" class="result"> </p>
</form>

Upvotes: 1

Dexterians
Dexterians

Reputation: 1021

Just change:

const radios = document.querySelector('input[name="discount"]:checked');

To:

const radios = document.querySelectorAll('input[name="discount"]:checked');

See working snippet:

const radios = document.querySelectorAll('input[name="discount"]:checked');
const toast = document.querySelector('#resultToast');
const priceIn = document.querySelector("#priceInput");

if (radios) {
  document.querySelectorAll('input[name="discount"]').forEach((elem) => {
    elem.addEventListener("change", function(event) {
       radios.value = event.target.value;
       console.log(radios.value);
        if(priceIn){
          toast.textContent = 'final price:  ' + radios.value * priceIn.value;
        }
    });
  });
}

if(priceIn){
  priceIn.addEventListener('input', updateValue);
}

function updateValue(e) {
  toast.textContent = 'final price:  ' + e.target.value * radios.value;
}
<div>
      <input type="radio" value="0.1" id="radioOne"   name="discount"  />
      <label for="radioOne" class="radio">10%</label>
</div>
<div>
      <input type="radio" value="0.2" id="radioTwo"   name="discount" />
      <label for="radioTwo" class="radio">20%</label>
</div>
<div>
      <input type="radio" value="0.3" id="radioThree"  name="discount" checked />
      <label for="radioThree" class="radio">30%</label>
</div>

<input type="number" name="price" id="priceInput" placeholder="Price">

<p id="resultToast"> </p>

Reason for this is because you stored the initial

document.querySelector('input[name="discount"]:checked');

value as radios. Now that we look for all, it changes accordingly.

Upvotes: 1

Related Questions