Benny Benny - 3 months ago 14
HTML Question

Javascript not updating hidden field correctly

The Javascript code below should update the value of a hidden field which has the

ID=adjustChk
to 'y' if any of the radio buttons are selected as
Yes
.

It updates the field as expected, but if any of the radios are changed back to 'n' the hidden field is also updated to 'n'. Hoped the break would exit the for loop when a 'y' was encountered, but this doesn't behave the way I'd hoped.



window.onload = function() {
var ele = document.getElementsByTagName("input");
var hid = document.getElementById("adjustChk");
var chkItm = "";
for(var i = 0, item; item = ele[i]; i++){
item.addEventListener("click", function() {
chkItm = this.value;
for (var i = 0; i < ele.length; i++){
if(chkItm === 'y'){
hid.value = 'y';
break;
} else {
hid.value = 'n';
}
};
});
};
};

<div>
Yes<input type="radio" name="radio1" value="y" />
No<input type="radio" name="radio1" value="n" checked="checked" />
</div>
<div>
Yes<input type="radio" name="radio2" value="y" />
No<input type="radio" name="radio2" value="n" checked="checked" />
</div>
<div>
Yes<input type="radio" name="radio3" value="y" />
No<input type="radio" name="radio3" value="n" checked="checked" />
</div>

<input id="adjustChk" type="hidden" value="n" />





I'm still getting the hang of JS, so if there is also a better way using plain Jasvascript it would be helpful to see it!

Answer

The problem is that you're looking at the value of the radio button that was clicked, but what you really want is to look at the checked state of all of the "yes" radio buttons instead.

I'd probably get a true array of elements (using the slice trick described in the "array-like" part of this answer), use Array#forEach to hook up the handler (but the for loop is fine too), and when processing a click, use Array#some to get a flag for whether any of the buttons that's checked has value "y".

Here's an example, see the comments; I made the hidden field visible so it was easy to see its value at any given time:

// Get the radio buttons, convert the NodeList into a true array
var ele = Array.prototype.slice.call(document.getElementsByTagName("input"));

// Get the hidden field
var hid = document.getElementById("adjustChk");

// Attach a handler to all of our radio buttons
ele.forEach(function(el) {
  el.addEventListener("click", radioHandler, false);
});

function radioHandler() {
  // Set `hid.value` to "y" if any of the checked checkboxes have the value "y",
  // "n" otherwise
  hid.value = ele.some(function(el) {
    return el.checked && el.value === "y";
  }) ? "y" : "n";
}
<div> 
  Yes<input type="radio" name="radio1" value="y" />
  No<input type="radio" name="radio1" value="n" checked="checked" />
</div>
<div> 
  Yes<input type="radio" name="radio2" value="y" />
  No<input type="radio" name="radio2" value="n" checked="checked" />
</div>
<div> 
  Yes<input type="radio" name="radio3" value="y" />
  No<input type="radio" name="radio3" value="n" checked="checked" />
</div>

<input id="adjustChk" type="text" value="n" />

But, here's a version using for loops instead:

// Get the radio buttons
var ele = document.getElementsByTagName("input");

// Get the hidden field
var hid = document.getElementById("adjustChk");

// Attach a handler to all of our radio buttons
for (var i = 0; i < ele.length; ++i) {
  ele[i].addEventListener("click", radioHandler, false);
}

function radioHandler() {
  // Assume no "yes" radio buttons are checked
  hid.value = "n";
  for (var i = 0; i < ele.length; ++i) {
    // Get the radio button for this loop iteration
    var el = ele[i];
    // If it's checked and has value "y", update the value and we're done
    if (el.checked && el.value === "y") {
      hid.value = "y";
      break;
    }
  }
}
<div> 
  Yes<input type="radio" name="radio1" value="y" />
  No<input type="radio" name="radio1" value="n" checked="checked" />
</div>
<div> 
  Yes<input type="radio" name="radio2" value="y" />
  No<input type="radio" name="radio2" value="n" checked="checked" />
</div>
<div> 
  Yes<input type="radio" name="radio3" value="y" />
  No<input type="radio" name="radio3" value="n" checked="checked" />
</div>

<input id="adjustChk" type="text" value="n" />


Just for fun, here's that first example using ES2015 (aka "ES6"):

// Get the radio buttons as a true array
let ele = Array.from(document.getElementsByTagName("input"));

// Get the hidden field
let hid = document.getElementById("adjustChk");

// Attach a handler to all of our radio buttons
ele.forEach(el => {
  el.addEventListener("click", radioHandler, false);
});

function radioHandler() {
  // Set `hid.value` to "y" if any of the checked checkboxes have the value "y",
  // "n" otherwise
  hid.value = ele.some(el => el.checked && el.value === "y") ? "y" : "n";
}
<div> 
  Yes<input type="radio" name="radio1" value="y" />
  No<input type="radio" name="radio1" value="n" checked="checked" />
</div>
<div> 
  Yes<input type="radio" name="radio2" value="y" />
  No<input type="radio" name="radio2" value="n" checked="checked" />
</div>
<div> 
  Yes<input type="radio" name="radio3" value="y" />
  No<input type="radio" name="radio3" value="n" checked="checked" />
</div>

<input id="adjustChk" type="text" value="n" />

Comments