Hi,
you are using form controls. You want another form control, a submit button. So I’m going to assume this is actually a form, rather than just a Javascripted feedback mechanism.
Quickie idea (untested!!, written in browser):
function setSubmit () {
var radios = [],
inputs = document.forms[your form id].elements,
allInputs = inputs.length;
for (var r=0; r<allInputs; r++) {
if (inputs[r].type===radio) {
radios.push(inputs[r]);
}
}
var len = radios.length;
for (var i=0; i<len; i++) {
//if at least one pass is checked, form not blank
if (/y/.test(radios[i].id && radios[i].checked) {
submit.style.color='#ffffff';
submit.style.backgroundColor='#008800';
submit.value='PASS';
}
else if (/n/.test(radios[i].id && radios[i].checked) {
submit.style.color='#ffffff';
submit.style.backgroundColor='#cc0000';
submit.value='FAIL';
break; //only need one fail to FAIL, no point in checking more
}
}
}
It might flicker green once if it’s a long form. Again, untested but I’d start with something like this.
Also, you might be missing out on the true function of radio buttons. Radio buttons get their name from a style of buttons we used to have in places like car radio controls: mechanically, only one button could be pressed at a time. Pressing a non-pressed button would mechanically unpress any pressed button. Form radio buttons do the same: if you select one radio button from a group (a group shares a name, and your radios don’t have names yet), no others may also be selected, unlike checkboxes. (It is recommended that you set one of them ‘checked’ by default. If this doesn’t make sense for your form, consider using something else to show pass/fail to the user.)
So with that in mind, your script could probably rely on that to simply select the appropriate radio button in the group and the other will automagically deselect itself for you (I’m not 100% sure of this when the manip is done by JS rather than the user, but it should hold true).
I also wrote your Javascript in an object wrapper, just because it’s what I’m used to. You don’t have to.
Untested and written in my browser, and prolly lots of silly typos:
<form id="passfail" method="get" action="youraction.url">
<fieldset>
<div>
<label for="UserIn1">Enter your number: </label>
<input type="text" id="UserIn1" name="userin1" data-lownum="4" data-hinum="6">
</div>
<div class="pass">
<input type="radio" id="pfy1" name="pf1">
<label for="pfy1"> Pass</label>
</div>
<div class="fail">
<input type="radio" id="pfn1" name="pf1">
<labe for="pfn1"> Fail</label>
</div>
</fieldset>
<fieldset>
<div>
<label for="UserIn2">Enter your number: </label>
<input type="text" id="UserIn2" name="userin2" data-lownum="3.2" data-hinum="3.4">
</div>
<div class="pass">
<input type="radio" id="pfy2" name="pf2"
<label for="pfy2"> Pass</label>
</div>
<div class="fail">
<input type="radio" id="pfn2" name="pf2">
<label for="pfn2"> Fail</label>
</div>
</fieldset>
<div>
<input type="submit" value="Default text">
</div>
</form>
<script>
var PF = {
//globalz
var inputs = document.forms['passfail'].elements, //be aware some browsers add fieldset to this list, others don't
submit = inputs[inputs.length-1];
init: function() {
var len = PF.inputs.length;
for (var i=0; i<len; i++) {
var input = PF.inputs[i];
if (input.type===text) {
//modern browsers
if(document.addEventListener) {
input.addEventListener('change', PF.check, false);
}
//IE<9
else {
input.attachEvent('onchange', PF.check);
}
}
}
},
disable: function(radios,groupName) {
for (var i=0; i<radios.length; i++) {
if (radios[i].name == groupName) {
radios[i].disabled = true;
}
}
},
setSubmit: function() {
var radios = [],
allInputs = PF.inputs.length;
for (var r=0; r<allInputs; r++) {
if (PF.inputs[r].type===radio) {
radios.push(PF.inputs[r]);
}
}
var len = radios.length;
for (var i=0; i<len; i++) {
//if at least one pass is checked, form not blank
if (/^pfy\\d/.test(radios[i].id && radios[i].checked) {
PF.submit.style.color='#ffffff';
PF.submit.style.backgroundColor='#008800';
PF.submit.value='PASS';
}
else if (/^pfn\\d/.test(radios[i].id && radios[i].checked) {
PF.submit.style.color='#ffffff';
PF.submit.style.backgroundColor='#cc0000';
PF.submit.value='FAIL';
break; //only need one fail to FAIL, no point in checking more
}
}
},
passFail: function(this,lownum,hinum,pfy,pfn) {
var UserInput = parseFloat(this.value),
groupName = pfy.name; //name of radio group within this fieldset only
if (isNaN(UserInput)) {
return; //send some error message here;
}
if (UserInput >= lownum && UserInput <= hinum) {
pfy.checked = true; //should uncheck the other(s)
this.style.backgroundColor = '#78e154';
}
else {
pfn.checked = true;
this.style.backgroundColor = '#de4948';
}
var radios = document.forms['passfail'].elements[groupName];
PF.disable(radios,groupName);
PF.setSubmit();
},
check: function(this) {
var fieldset = this.parentNode.parentNode,
localInputs = fieldset.getElementsByTagName('input'), //local to clicked input only
lownum = parseFloat(this.getAttribute('data-lownum')),
hinum = parseFloat(this.getAttribute('data-hinum')),
pfy,
pfn;
for (var i=0; i<localInputs.length; i++) {
if (/^pfy\\d/.test(localInputs[i].id)) {
pfy = localInputs[i];
return;
}
else if (/^pfn\\d/.test(localInputs[i].id)) {
pfn = localInputs[i];
return;
}
}
passFail(this,lownum,hinum,pfy,pfn);
}
};
if(document.addEventListener) {
window.addEventListener('load', PF.init, false);
}
else if(window.attachEvent) {
window.attachEvent('onload', PF.init);
}
</script>
CSS (in the <head>) for your inputs… instead of inline:
#passfail input[type=text] {
width: 60px;
font-weight: bold;
}
#passfail input[type=text]:focus {
background-color: #fff;
}
.pass, .fail {
text-align: center;
background-color: #78e154;
}
.fail {
background-color: #de4948;
}
/*hide these labels*/
.pass label, .fail label {
position: absolute;
left: -999em;
height: 0;
}
I realise you posted two sets of inputs in your example but there might be many more. I also see there’s lots of other data besides the inputs. There’s nothing wrong with having a table inside a form, but I do generally encourage using forms if you’re doing “form stuff”.
If your setup were
<form id="passfail" method="post" action="actionURL">
<table>
...
</table>
</form>
Then tr’s would replace fieldsets in the code above.