...

View Full Version : Array of radio button objects in a form?



Opally
06-06-2007, 09:48 PM
Howdy!

I'm trying to create an array of form elements, some radio button groups. Then I can have an array of arrays, and cycle through them all, testing their values, because a radio button group is itself an array, correct?

I'm getting an error: 'array' is undefined, from this code:

snippet of the function

function showChoices(){
var radiogroup = new array(6)
radiogroup[0] = document.prekprofile["monitorperf"]
radiogroup[1] = document.prekprofile["ckpat"]
radiogroup[2] = document.prekprofile["prek1"]
radiogroup[3] = document.prekprofile["prek2"]
radiogroup[4] = document.prekprofile["k8"]
radiogroup[5] = document.prekprofile["natconf"]

I also tried defining the elements of the array like this, but I get the same error:
radiogroup[0] = document.forms[0].monitorperf

What this function is supposed to do: my form uses responses to some yes/no options (radio buttons) to show or hide other fields. The show/hide works fine, but if I return to my page to edit data (using PHP session) the show/hide settings go back to their default CSS display:none setting. So I need to call a function for the body onLoad to test the radio button selected values and show the revealed fields. I'm probably doing this in a very clumsy way, but let's get my array sorted out first, please, oh gurus of Javascript!

thanks!

--Opally

brandonH
06-06-2007, 09:52 PM
there are multiple possible solutions but I will need to know exactly how you are using theradio buttons to tell you for sure. If you can please provide your source code.

Opally
06-06-2007, 10:34 PM
thanks for the reply!

Here's an example of how I'm managing show/hide of related fields with radio buttons.

The form is here:
http://www.coreknowledge.org/secure/html_forms/prekprofile.php

Here's the HTML for one radio button set:

<label>Do you use the <em>Core Knowledge Preschool Assessment Tool</em>?</label>
<span class="redstar">*</span> &nbsp;
<label>yes
<input name="ckpat" type="radio" value="yes" id="ckpatyes" onClick="hideHowlong(this)"<?php if( $_SESSION['prekprofile']['ckpat'] == 'yes' ) { ?> checked="checked"<?php } ?>>
</label>
&nbsp;&nbsp;
<label>no
<input name="ckpat" type="radio" value="no" id="ckpatno" onClick="hideHowlong(this)"<?php if( $_SESSION['prekprofile']['ckpat'] == 'no' ) { ?> checked="checked"<?php } ?>>
</label>

Here's the function to hide/show its related div containing other fields:

function hideHowlong(choice) {
if (choice.value == "yes") {
document.getElementById('ckpathowlong').style.display='inline';
} else if (choice.value == "no") {
document.getElementById('ckpathowlong').style.display='none';
}
return true;
}


Here's my crummy code to call in body onload, to restore visibility to the divs when their radio buttons tell them to... there should be a better way, but unfortunately I'm not much of a programmer. That's why I love you guys!

It is untested, since I can't get past the problem with my array, for starters.

Not all the radio buttons work the same way, for logical reasons; prek1 and prek2 are interdependent and test on "no" to show their extra fields, instead of "yes" as the other radio button groups do.

NOT all radio button groups control dependent fields in this form.


function showChoices(){
var radiogroup = new array(6)
radiogroup[0] = document.prekprofile["monitorperf"]
radiogroup[1] = document.prekprofile["ckpat"]
radiogroup[2] = document.prekprofile["prek1"]
radiogroup[3] = document.prekprofile["prek2"]
radiogroup[4] = document.prekprofile["k8"]
radiogroup[5] = document.prekprofile["natconf"]

for (var i = 0; i < radiogroup.length; i++) {
for (var j=0; j<radiogroup[i].length; j++){
if (radiogroup[i][j].checked == false) {
break;
}
if (radiogroup[i][j].value == "yes") {
if (/(prek)/.test(radiogroup[i].name)) {
hideSeqomit(radiogroup[i][j]); }
if (radiogroup[i].name == "monitorperf") {
document.getElementById('assmtsfields').style.display='inline';
}
if (radiogroup[i].name == "ckpat") {
document.getElementById('ckpathowlong').style.display='inline';
}
if (radiogroup[i].name == "k8") {
document.getElementById('ckgrades').style.display='inline';
}
if (radiogroup[i].name == "natconf") {
document.getElementById('natconfyears').style.display='inline';
}
} else if ((radiogroup[i][j].value == "no") && (/(prek)/.test(radiogroup[i].name))) {
hideSeqomit(radiogroup[i][j]); } // end else if
} // for j
} //for i
} // function

I'd love to hear your ideas how to accomplish this. Again, the thing is, on return to the page, restore the visibility of the fields, according to their radio button selections.

Attaching my whole javascript for these functions, and PHP form. Don't worry about the Selects, they are defined in a separate PHP Include.

---Opally

glenngv
06-06-2007, 11:09 PM
First of all, this:

var radiogroup = new array(6)
should be:

var radiogroup = new Array(6)
But you don't need an array at all (not that a group of radio buttons is already an array).

You can simply do it this way. Since most of the radios behave the same way and only 2 groups (prek1 & prek2) behave differently, then you can have a special case for those 2 groups. If I understand your specs correctly, then this is the solution.


function showHide(choice, divId) {
if (choice.name.indexOf("prek")!= -1){
var rad = (choice.name=="prek1")? choice.form.prek2 : choice.form.prek1;
if (choice.value=="no" || rad.value=="no"){
document.getElementById(divId).style.display = 'inline';
}
else if (choice.value=="yes" && rad.value=="yes"){
document.getElementById(divId).style.display = 'none';
}

}
else {
document.getElementById(divId).style.display = (choice.value=="yes") ? 'inline':'none';
}
}



<input name="prek1" type="radio" value="yes" id="prek1yes" onclick="showHide(this, 'seqomit');" />
<input name="prek1" type="radio" value="no" id="prek1no" onclick="showHide(this, 'seqomit');" />
...
<input name="natconf" type="radio" value="yes" id="natconfyes" onClick="showHide(this, 'natconfyears');" />
<input name="natconf" type="radio" value="no" id="natconfno" onClick="showHide(this, 'natconfyears');" />

Opally
06-07-2007, 06:43 PM
Very sweet script, Glenn, thank you! I like it a lot.

One problem: rad.value is undefined.

The first time through it does execute correctly, but then it never will hide the div if the selections change.

I added a little Alert to help me figure out why it isn't working, you can see it here:
http://www.coreknowledge.org/secure/html_forms/prekprofile.php
go to "Is the entire Preschool Sequence being used?" and see the little table of radio buttons.

I also tried rewriting it this way, with no change:


function showHide(choice, divId) {
if (choice.name.indexOf("prek")!= -1){
var rad = (choice.name=="prek1")? document.forms[0].prek2 : document.forms[0].prek1;
alert ("choice.name = " + choice.name + " and rad.name = " + rad.name + " and rad.value = " + rad.value);
if (choice.value=="no" || rad.value=="no"){
document.getElementById(divId).style.display = 'inline';
}
else if (choice.value=="yes" && rad.value=="yes"){
document.getElementById(divId).style.display = 'none';
}
}
else {
document.getElementById(divId).style.display = (choice.value=="yes") ? 'inline':'none';
}
}


var rad gets defined as [object], but rad.name and rad.value are undefined.

Would love to see a solution.

I also want to display the divs on return to the page after review, is there a neat way to do a function like that? Probably as an onload function?

---Opally

glenngv
06-07-2007, 07:13 PM
function showHide(choice, divId) {
if (choice.name.indexOf("prek")!= -1){
var rad = (choice.name=="prek1")? getSelectedRadio(choice.form.prek2) : getSelectedRadio(choice.form.prek1);
if (choice.value=="no" || !rad || rad.value=="no"){
document.getElementById(divId).style.display = 'inline';
}
else if (choice.value=="yes" && rad && rad.value=="yes"){
document.getElementById(divId).style.display = 'none';
}

}
else {
document.getElementById(divId).style.display = (choice.value=="yes") ? 'inline':'none';
}
}

function getSelectedRadio(radGroup){
for (var i=0; i<radGroup.length; i++){
if (radGroup[i].checked) return radGroup[i];
}
return null; //nothing selected
}
I assume that if the other prek radio button group has no selection, the div will still be displayed.

Opally
06-07-2007, 08:39 PM
Works like a charm, very elegant. Thanks a TON, Glenn! I have learned a lot from you guys.

Here's a related question: how best to deal with the display of the divs on load? I was using a CSS display:none for the div styles, but that leads me into difficulty when I return to edit data; divs that contain data do not display unless their radio buttons are clicked again, rather silly.

I was trying to write a rather messy looking onload function to go through the array of radio button arrays, test their condition, and display their divs. My code didn't work, tho I did learn to declare an array as an Array, not an "array". :cool:

But maybe there could be an initialize function that sets all the divs to display:none or display:inline depending on the radio button values or lack of values. Unfortunately I don't see how I can recycle your lovely code since I won't have values to pass to it. Hmm.

---Opally

glenngv
06-07-2007, 09:25 PM
function showHideOnload(choiceName, divId) {
var frm = document.forms[0];
var radGroup = frm.elements[choiceName];
var choice = getSelectedRadio(radGroup);
if (choiceName.indexOf("prek")!= -1){
var rad = (choiceName=="prek1")? getSelectedRadio(frm.prek2) : getSelectedRadio(frm.prek1);
if (!choice || choice.value=="no" || !rad || rad.value=="no"){
document.getElementById(divId).style.display = 'inline';
}
else if (choice.value=="yes" && rad && rad.value=="yes"){
document.getElementById(divId).style.display = 'none';
}

}
else {
document.getElementById(divId).style.display = (choice && choice.value=="yes") ? 'inline':'none';
}
}

function getSelectedRadio(radGroup){
for (var i=0; i<radGroup.length; i++){
if (radGroup[i].checked) return radGroup[i];
}
return null; //nothing selected
}

function init(){
var arr = new Array(
['prek1', 'seqomit'],
['prek2', 'seqomit'],
//...and so on
['natconf', 'natconfyears'] //no comma at the last element
);

for (var i=0; i<arr.length; i++){
showHideOnload(arr[i][0], arr[i][1]);
}
}

window.onload = init; //combine with other onloads if any

Opally
06-07-2007, 10:11 PM
This is mostly working, I think, but you probably laugh at my clutzy code. :D

<body onload ="showChoices();">


function showChoices(){
var radiogroup = new Array(7)
radiogroup[0] = document.prekprofile.monitorperf
radiogroup[1] = document.prekprofile.ckpat
radiogroup[2] = document.prekprofile.prek1
radiogroup[3] = document.prekprofile.prek2
radiogroup[4] = document.prekprofile.k8
radiogroup[5] = document.prekprofile.training
radiogroup[6] = document.prekprofile.natconf

for (var i = 0; i < radiogroup.length; i++) {
for (var j=0; j<radiogroup[i].length; j++){
if (radiogroup[i][j].checked == false) {
break;
}
if (radiogroup[i][j].value == "yes") {
if (/(prek)/.test(radiogroup[i][j].name)) {
showHide(radiogroup[i][j],"seqomit");
}
if (radiogroup[i][j].name == "monitorperf") {
showHide(radiogroup[i][j],"assmtsfields");
}
if (radiogroup[i][j].name == "ckpat") {
showHide(radiogroup[i][j],"ckpathowlong");
}
if (radiogroup[i][j].name == "k8") {
showHide(radiogroup[i][j],"ckgrades");
}
if (radiogroup[i][j].name == "training") {
showHide(radiogroup[i][j],"modules");
}
if (radiogroup[i][j].name == "natconf") {
showHide(radiogroup[i][j],"natconfyears");
}
} else if ((radiogroup[i][j].value == "no") && (/(prek)/.test(radiogroup[i][j].name))) {
showHide(radiogroup[i][j],"seqomit");
} // end else if
} // for j
} //for i
} // function

Opally
06-07-2007, 10:49 PM
Love your work. Very nice. And I learn from it.

For some reason, window.onload wasn't working, maybe because of my validation script?

fV.addEvent(window, 'load', fV.init, false);

there's alread an init function in the validation script, so I renamed this one, and I put a call to initDivs() in body onload. That's not the preferred way of doing things, I understand, but I don't really want to modify the validation script. It's something I got from a book. But it does make it hard to add more window.onload events.

Only remaining issue is that on a clean page load (new session), that pesky seqomit div shows, before anything is checked. It shouldn't be showing. The other divs do exactly as they should. Not sure what to change there to fix that.

---Opally

glenngv
06-07-2007, 11:08 PM
What should be the behavior of the seqomit div if nothing is checked in both prek1 & prek2 radio groups? The way I coded is the div will only be hidden when both "yes" are checked, other than that it will be shown. If this is wrong, then please explain the expected behavior again.

Opally
06-08-2007, 04:01 PM
Hi, Glenn.

Yes, I'd like the seqomit div to be hidden when nothing is checked.

---Opally

Opally
06-08-2007, 11:06 PM
ah I got it!


if (choiceName.indexOf("prek")!= -1){
var rad = (choiceName=="prek1")? getSelectedRadio(frm.prek2) : getSelectedRadio(frm.prek1);
if (!choice || !rad || (choice.value=="yes" && rad && rad.value=="yes")) {
document.getElementById(divId).style.display = 'none';
}
else if (!choice || choice.value=="no" || !rad || rad.value=="no"){
document.getElementById(divId).style.display = 'inline';
}

}

thanks for all the help, I sure do appreciate it!

---Opally



EZ Archive Ads Plugin for vBulletin Copyright 2006 Computer Help Forum