...

View Full Version : Disable checkboxes when changing option



pdoes
08-25-2008, 09:21 PM
This is my first javascript I've written and it works.
What I would like to know if this is OK or if it could be improved. Improvement can make use of jQuery.

The goal is to disable/enable checkboxes, change the color and unselect if checked and not available, based on the pulldown menu within the same form.
Example: Selecting QB disables checkboxes Spell (id=3) and Wand (id=4).
This is a simple example, the full version could have multiple forms in the same page and several more checkboxes to be checked.


<html>
<head>
<style type="text/css">
.avail {color: #000000}
.notavail {color: #00ff00 }
</style>
</head>
<body>
<script language="JavaScript">
<!--
function disable(z)
{
var l = z.sel.value;
if (l == 'QB') var c=new Array(3,4);
if (l == 'QC') var c=new Array(0,3);
for (x=0;x<z.elements.length;x++){
if (z.elements[x].type == 'checkbox'){
z.elements[x].disabled = false;
z.elements[x].parentNode.className = 'avail';
var id=z.elements[x].id;
for (i in c) {
if (id == c[i]) {
z.elements[x].checked = false;
z.elements[x].disabled = true;
z.elements[x].parentNode.className = 'notavail';
}
}
}
}
}
//-->
</script>
<form name="gratis">
<select name="sel" onchange="disable(document.forms.gratis)">
<option value="QA">Quest A</option>
<option value="QB">Quest B</option>
<option value="QC">Quest C</option>
</select>
<br />
<div class="avail">
<input name="1" id="1" value="Light" type="checkbox"/> Light <BR />
</div>
<div class="avail">
<input name="2" id="2" value="Books" type="checkbox"/> Books <BR />
</div>
<div class="avail">
<input name="3" id="3" value="Spell" type="checkbox"/> Spell <BR />
</div>
<div class="avail">
<input name="4" id="4" value="Wand" type="checkbox"/> Wand <BR />
</div>
</form>

</body>
</html>

Thanks in advance.
Peter

chaosprime
08-25-2008, 09:24 PM
One thing that leaps out at me is that this isn't good practice:
if (l == 'QB') var c=new Array(3,4);
if (l == 'QC') var c=new Array(0,3);
I'd rewrite it:
var c;
if (l == 'QB')
c=new Array(3,4);
if (l == 'QC')
c=new Array(0,3);

pdoes
08-25-2008, 10:07 PM
One thing that leaps out at me is that this isn't good practice:
if (l == 'QB') var c=new Array(3,4);
if (l == 'QC') var c=new Array(0,3);
I'd rewrite it:
var c;
if (l == 'QB')
c=new Array(3,4);
if (l == 'QC')
c=new Array(0,3);

Thanks, this is the kind of feedback I was hoping for.

Cranford
08-25-2008, 11:20 PM
--- error double post

Cranford
08-25-2008, 11:24 PM
@pdoes, you may want to try this, using DOM methods. It will work with multiple forms on the page, each with its own number of checkboxes. The "value" of the select list is a string of the ordinal numbers of the checkboxes that will be disabled for that selection. Zero is the ordinal number for the first checkbox. e.g. if there are 4 checkboxes, and a selection's value is "2,3" then the 3rd and 4th checkboxes will be disabled.




<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>Any Title</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<script type="text/javascript">

function modify(currForm,nValue){

var nDisable = [];
var nBoxes = [];
if (nValue != "")
{
nDisable = nValue.split(",");
}
var nForm = document.forms[currForm];
for (i=0; i<nForm.length; i++)
{
if (nForm[i].type == "checkbox")
{
nBoxes[nBoxes.length] = nForm[i];
}
}
for (i=0; i<nBoxes.length; i++)
{
nBoxes[i].disabled = false;
nBoxes[i].parentNode.style.color = "black";
}
for (i=0; i<nDisable.length; i++)
{
nBoxes[nDisable[i]].disabled = true;
nBoxes[nDisable[i]].parentNode.style.color = "green";
}
}


</script>
<style type="text/css">

body {background-color: #eae3c6; margin-top: 60px;}
form {width: 620px; margin: auto; font-family: times; font-size: 12pt;}
fieldset {width: 620px; background-color: #f0fff0; border: 1px solid #87ceeb;}
legend {font-family: times; font-size: 14pt; color: #00008b; background-color: #87ceeb; padding-left: 3px; padding-right: 3px; margin-bottom: 5px;}
select {width: 150px; margin-bottom: 5px; margin-left: 5px;}
label {display: block; margin-left: 5px;}
.submitBtn {font-family: tahoma; font-size: 10pt; display: block; margin-left: auto; margin-right: auto; margin-top: 5px; margin-bottom: 5px;}

</style>
</head>
<body>
<form name="gratis" action="" method="post">
<fieldset>
<legend>Form</legend>
<select onchange="modify(this.form.name,this.value)">
<option value=""> Quest A </option>
<option value="2,3"> Quest B </option>
<option value="2"> Quest C </option>
</select>
<label><input type="checkbox" name="choices[]" value="light"> Light </label>
<label><input type="checkbox" name="choices[]" value="books"> Books </label>
<label><input type="checkbox" name="choices[]" value="spell"> Spell </label>
<label><input type="checkbox" name="choices[]" value="wand"> Wand </label>
<input type="submit" name="submit" value="Submit" class="submitBtn">
</fieldset>
</form>
</body>
</html>

pdoes
08-25-2008, 11:40 PM
@pdoes, you may want to try this, using DOM methods. It will work with multiple forms on the page, each with its own number of checkboxes. The "value" of the select list is a string of the ordinal numbers of the checkboxes that will be disabled for that selection. Zero is the ordinal number for the first checkbox. e.g. if there are 4 checkboxes, and a selection's value is "2,3" then the 3rd and 4th checkboxes will be disabled.




<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>Any Title</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<script type="text/javascript">

function modify(currForm,nValue){

var nDisable = [];
var nBoxes = [];
if (nValue != "")
{
nDisable = nValue.split(",");
}
var nForm = document.forms[currForm];
for (i=0; i<nForm.length; i++)
{
if (nForm[i].type == "checkbox")
{
nBoxes[nBoxes.length] = nForm[i];
}
}
for (i=0; i<nBoxes.length; i++)
{
nBoxes[i].disabled = false;
nBoxes[i].parentNode.style.color = "black";
}
for (i=0; i<nDisable.length; i++)
{
nBoxes[nDisable[i]].disabled = true;
nBoxes[nDisable[i]].parentNode.style.color = "green";
}
}


</script>
<style type="text/css">

body {background-color: #eae3c6; margin-top: 60px;}
form {width: 620px; margin: auto; font-family: times; font-size: 12pt;}
fieldset {width: 620px; background-color: #f0fff0; border: 1px solid #87ceeb;}
legend {font-family: times; font-size: 14pt; color: #00008b; background-color: #87ceeb; padding-left: 3px; padding-right: 3px; margin-bottom: 5px;}
select {width: 150px; margin-bottom: 5px; margin-left: 5px;}
label {display: block; margin-left: 5px;}
.submitBtn {font-family: tahoma; font-size: 10pt; display: block; margin-left: auto; margin-right: auto; margin-top: 5px; margin-bottom: 5px;}

</style>
</head>
<body>
<form name="gratis" action="" method="post">
<fieldset>
<legend>Form</legend>
<select onchange="modify(this.form.name,this.value)">
<option value=""> Quest A </option>
<option value="2,3"> Quest B </option>
<option value="2"> Quest C </option>
</select>
<label><input type="checkbox" name="choices[]" value="light"> Light </label>
<label><input type="checkbox" name="choices[]" value="books"> Books </label>
<label><input type="checkbox" name="choices[]" value="spell"> Spell </label>
<label><input type="checkbox" name="choices[]" value="wand"> Wand </label>
<input type="submit" name="submit" value="Submit" class="submitBtn">
</fieldset>
</form>
</body>
</html>


I love your coding, really clean and understandable..
The problem with this solution is the fact I'll be needing the value of the dropdown later. The solution will be encapsulated in a PHP program and depending on the value of the dropdown a search will be performed using the checkboxes as options.

Cranford
08-25-2008, 11:49 PM
So, just append the value to the string:

value="2,3,Light"

then drop the last element of the array after the split:

if (nValue != "")
{
nDisable = nValue.split(",");
nDisable.length = nDisable.length - 1;
}

I'm certain, that upon POST, you can manipulate the select list value to do the same thing, and then use the "Light" in your MySQL query.

pdoes
08-26-2008, 12:22 PM
OK so I did some rewriting and here's what I came up with:

<html>
<head>
<title>Title</title>
<style type="text/css">
.disabled { color : green }
</style>
</head>
<body>
<form id="gratis" action="" method="post">
<select name="sel">
<option value="QA"> Quest A </option>
<option value="QB"> Quest B </option>
<option value="QC"> Quest C </option>
</select>
<p><label><input type="checkbox" name="choices[]" value="light"> Light </label></p>
<p><label><input type="checkbox" name="choices[]" value="books"> Books </label></p>
<p><label><input type="checkbox" name="choices[]" value="spell"> Spell </label></p>
<p><label><input type="checkbox" name="choices[]" value="wand"> Wand </label></p>
<p><input type="submit" name="submit" value="Submit"</p>
</form>

<script type="text/javascript">
function inArray(array, value) {
for (var i = 0; i < array.length; i += 1) {
if (value === array[i]) {
return true;
}
}
}

function modify(){

var Form = this.form,
Selected = Form.elements.sel.value,
Disabled = {
'QB': ['spell' , 'wand'],
'QC': ['spell']
},
Element;

if (Disabled[Selected]) {
for (i = 0; i < Form.elements.length; i++) {
Element = Form.elements[i];
if (Element.type == 'checkbox') {
if (inArray(Disabled[Selected], Element.value)) {
Element.disabled = true;
Element.checked = false;
Element.parentNode.className = 'disabled';
} else {
Element.disabled = false;
Element.parentNode.className = '';
}
}
}
}
}

var form=document.getElementById('gratis');
form.elements.sel.onchange = modify;

</script>
</body>
</html>

I'm using the value of the checkboxes to make it more clear what's happening and I can move the checkboxes around if needed.

The HTML layout will change in the final version

Suggestions are still welcome.



EZ Archive Ads Plugin for vBulletin Copyright 2006 Computer Help Forum