Multiple select onclick disable another form field

F

Forti2ude

Hello,

I have a simple form...

<form>
<select name="foo" multiple>
<option value="1">one</option>
<option value="2">two</option>
<option value="3">three</option>
</select>

<input type="text" name="boo" DISABLED>
<input type="text" name="goo" DISABLED>
</form>

When a user chooses any of the options in the "foo" multiselect, as
long as one of them is value 2, I need to enable the fields "boo" and
"goo".

Anyone have any tips? Can this be done? Thanks!
 
F

Fred Oz

Forti2ude said:
Hello,

I have a simple form... [snip]

When a user chooses any of the options in the "foo" multiselect, as
long as one of them is value 2, I need to enable the fields "boo" and
"goo".

Anyone have any tips? Can this be done? Thanks!

yup. You need to think whether if the user de-selects "2", should boo
and goo be cleared? I have used onMouseUp for convienience here, but
you should consider carefully what the user would like.

If they select 2, add some text, then select another value, the text box
should be disabled again. If the content isn't cleared, they have to
select 2 again, clear the text, then select their new option. A reset
button fixes this but requires them to actually reset the form, then
select the new value.

You could also use a button to read the value and enable/disable the
text boxes.


<form>
<select name="foo" multiple onMouseUp="
var a = this.form.getElementsByTagName('option');
for (var i=0; i<a.length; ++i) {
if (a.selected == true && a.value == '2') {
this.form['boo'].removeAttribute('disabled');
this.form['goo'].removeAttribute('disabled');
break;
} else {
// clears the fields, you may not want to do this
this.form['boo'].value = '';
this.form['goo'].value = '';
// and disables them again
this.form['boo'].setAttribute('disabled','disabled');
this.form['goo'].setAttribute('disabled','disabled');
}
}
">
<option value="1">one</option>
<option value="2">two</option>
<option value="3">three</option>
</select>

<input type="text" name="boo" DISABLED>
<input type="text" name="goo" DISABLED>
</form>


However, the *best* option in my book is to only display the boxes if
the user has selected 2. If 2 becomes unselected, hid them again but
don't clear the content. If the user submits the form with some text in
the boxes but 2 not selected (the text boxes will be hidden so the user
may not realise there's something in them), deal with it at the server
by just ignoring the text.

Replace the select tag with the following:


<select name="foo" multiple onMouseUp="
var a = this.form.getElementsByTagName('option');
for (var i=0; i<a.length; ++i) {
if (a.selected == true && a.value == '2') {
// show them
this.form['boo'].style.visibility='visible';
this.form['goo'].style.visibility='visible';
break;
} else {
// hide them again
this.form['boo'].style.visibility='hidden';
this.form['goo'].style.visibility='hidden';
}
}
">


Note that you should probably hide the text boxes using JS in the first
place, else if JS is disabled and you hide them with styles (as I've
done) your users will never see the text boxes.

Also, you can use display = 'none' and display = '' but this may mess
with the layout of your page.

Fred.
 
F

Fred Oz

Fred Oz wrote:
[snip]
Note that you should probably hide the text boxes using JS in the first
place, else if JS is disabled and you hide them with styles (as I've
done) your users will never see the text boxes.

Ooops! To hide them with a style, use the following boo & goo inputs:

<input type="text" name="boo" style="visibility: hidden;">
<input type="text" name="goo" style="visibility: hidden;">

But note the note above about using JS to hide them!

Fred.
 
G

Grant Wagner

Forti2ude said:
Hello,

I have a simple form...

<form>
<select name="foo" multiple>
<option value="1">one</option>
<option value="2">two</option>
<option value="3">three</option>
</select>

<input type="text" name="boo" DISABLED>
<input type="text" name="goo" DISABLED>
</form>

When a user chooses any of the options in the "foo" multiselect, as
long as one of them is value 2, I need to enable the fields "boo" and
"goo".

Anyone have any tips? Can this be done? Thanks!

<form>
<select name="foo" multiple onchange="yourFunction(this.form);">
<option value="1">one</option>
<option value="2">two</option>
<option value="3">three</option>
</select>

<input type="text" name="boo" DISABLED>
<input type="text" name="goo" DISABLED>
</form>
<script type="text/javascript">
function getSelectValues(sel) {
var a = [];
if (sel && sel.options) {
var i = sel.options.length;
while (i-- > 0) {
if (sel.options.selected) {
a.push(sel.options.value);
}
}
}
return a;
}
function yourFunction(f) {
var values = getSelectValues(f.elements['foo']);
var oneOfTheValuesIsTwo = false;
var i = values.length;
while (i-- > 0) {
if (values == 2) {
oneOfTheValuesIsTwo = true;
break;
}
}

if (oneOfTheValuesIsTwo) {
f.elements['boo'].disabled = false;
f.elements['goo'].disabled = false;
} else {
f.elements['boo'].disabled = true;
f.elements['goo'].disabled = true;
}
}
</script>

Works in IE 6 and Firefox 1.0PR. Does not work in Opera 7.54 because the
onchange event does not fire when CTRL is held down and multiple items
are selected.

Changing the event to "onclick" makes it work in Firefox 1.0PR, but then
it does not work in IE 6 or Opera 7.54.

Changing the event to "onfocus" makes it work unreliably in all of the
browsers listed.

If there are only three options in the <select>, checkboxes would be
better and allow better control over what you want to do.
 
R

Richard Cornford

Forti2ude said:
I have a simple form...

<form>
<select name="foo" multiple>
<option value="1">one</option>
<option value="2">two</option>
<option value="3">three</option>
</select>

<input type="text" name="boo" DISABLED>
<input type="text" name="goo" DISABLED>
</form>

When a user chooses any of the options in the "foo"
multiselect, as long as one of them is value 2, I
need to enable the fields "boo" and "goo".

Anyone have any tips? Can this be done? Thanks!

If you disable any input in the HTML your are creating a form that
cannot work without javascript. There is no reason to do that as your
server side code still has to verify that whatever combination of fields
are submitted they still make sense (to prevent malicious submissions
being a problem). So your should initially disable the inputs when the
page loads with javascript:-

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>Form Control Conditional Disabling Demo</title>
<meta http-equiv="Content-Type"
content="text/html; charset=iso-8859-1">
<script type="text/javascript">
function setUpForm(){
var frmEl, sel, inptBoo, inptGoo;
if(
document.forms &&
(frmEl = document.forms['theFormName']) &&
(frmEl = (frmEl.elements||frm)) &&
(sel = frmEl['foo']) &&
(sel.options) &&
('number' == typeof sel.options.length) &&
(inptBoo = frmEl['boo']) &&
(inptGoo = frmEl['goo'])
){
sel.onchange = handleSelChange;
inptBoo.disabled = true;
inptGoo.disabled = true;
}
}
function handleSelChange(){
var c, opts = this.options, disable = true;
var frmEls = this.form.elements;
for(c = opts.length;c--;){
if((opts[c].selected)&&(opts[c].value == "2")){
disable = false;
break;
}
}
frmEls['boo'].disabled = disable;
frmEls['goo'].disabled = disable;
}
</script>

</head>
<body onload="setUpForm();">
<form action="" name="theFormName">
<select name="foo" multiple>
<option value="1">one</option>
<option value="2">two</option>
<option value="3">three</option>
</select>

<input type="text" name="boo">
<input type="text" name="goo">
</form>
</body>
</html>

Richard.
 
M

Michael Winter

On Tue, 05 Oct 2004 14:06:31 GMT, Grant Wagner

[snip]
Does not work in Opera 7.54 because the onchange event does not fire
when CTRL is held down and multiple items are selected.

I just found that drafting my own reply to this thread. Do you know if
it's a known bug?

[snip]

Mike
 
M

Michael Winter

[snip]
<form>
<select name="foo" multiple onMouseUp="
var a = this.form.getElementsByTagName('option');

That really isn't necessary.

var a = this.options;

is far more preferable.
for (var i=0; i<a.length; ++i) {
if (a.selected == true && a.value == '2') {
this.form['boo'].removeAttribute('disabled');
this.form['goo'].removeAttribute('disabled');


Why on Earth aren't you using the disabled property?

[snip]
// and disables them again
this.form['boo'].setAttribute('disabled','disabled');
this.form['goo'].setAttribute('disabled','disabled');

Here, too?

I'm also curious why you decided not to use a function.

[snip]
Note that you should probably hide the text boxes using JS in the first
place, else if JS is disabled and you hide them with styles (as I've
done) your users will never see the text boxes.

The same applies to disabling the controls, too.

[snip]

Mike
 
F

Fred Oz

Michael Winter wrote:
[snip]
var a = this.options;

is far more preferable.

Yep, and neater.

[snip]
Why on Earth aren't you using the disabled property?

'cos I figured there wasn't much difference between

this.form['boo'].setAttribute('disabled','disabled');

and

this.form['boo'].disabled = true;

The second method is neater though.

[snip]
I'm also curious why you decided not to use a function.

For a one-of, it doesn't seem necessary. It doesn't remove any lines of
code from the onClick and costs several lines in the header. Of course
it becomes more maintainable and available to be more widely used, if
the OP wants to tidy it up that way and use it eleswhere in the page, fine.

I'd replace:

this.form['goo'].disabled = false;

with something like:

// In the header
<script type="text/javascript">
function hideIt(a) {
a.disabled = false;
}

// In the body
hideIt(this.form['goo']);
[snip]
Note that you should probably hide the text boxes using JS in the
first place, else if JS is disabled and you hide them with styles (as
I've done) your users will never see the text boxes.


The same applies to disabling the controls, too.

Yes. Do you think it's better to hide them or disable them?

My issues with disabling them is that it creates a heap of "what if"
questions regarding a users interpretation and usage of the UI, whereas
hiding them raises very few (but still has its issues).

Fred.
 
M

Michael Winter

[snip]
this.form['boo'].setAttribute('disabled','disabled');

and

this.form['boo'].disabled = true;

The second method is neater though.

It's also better supported. The *Attribute methods aren't generally needed
for HTML documents. Their main use is with XML.

[snip]
Do you think it's better to hide [the controls] or disable them?

My issues with disabling them is that it creates a heap of "what if"
questions regarding a users interpretation and usage of the UI, whereas
hiding them raises very few (but still has its issues).

There's no reason why you can't do both. If a user agent isn't dynamic
enough to modify the style property, or CSS has been disabled or
overridden for some reason, the control is still disabled.

As far as one or the other is concerned, I'd prefer hiding, but only
because the rendering of disabled controls varies greatly. Early versions
of Mozilla and (all?) versions of IE don't change the rendering, they just
prevent focus and input. There are probably other browsers that are just
as ambiguous.

Mike
 
G

Grant Wagner

Michael said:
On Tue, 05 Oct 2004 14:06:31 GMT, Grant Wagner

[snip]
Does not work in Opera 7.54 because the onchange event does not fire
when CTRL is held down and multiple items are selected.

I just found that drafting my own reply to this thread. Do you know if
it's a known bug?

I don't know if it's a known bug, I'd certainly consider it a bug.

I don't actually use Opera and don't know anyone on our Intranet that
does, so it's more of an academic interest than a real problem for me at
this point. I just usually test in it as a "sanity check". I like having
scripts that work on any browser our users might possibly run, although as
I said, it's not a disaster for me if it does not work in Opera.

If you have an interest in Opera's success, I'd definitely pass it along
to them as a possible bug to be fixed. Perhaps someone with the beta of
7.60 could confirm if the problem exists there as well?
 
F

Forti2ude

Richard, this satisfies my requirements. Thank you!
To everyone else, I also thank you. Very informative.

-Mike
 
R

Richard Cornford

Forti2ude said:
Richard, this satisfies my requirements. Thank you!
To everyone else, I also thank you. Very informative.
<snip>

Drat, now I have to own up to the mistake. ;) That line should be:-

(frmEl = (frmEl.elements||frmEl)) &&

The - frm - identifier was left over from an earlier revision.

It also occurred to me afterwards that the - for - could be a - while -
loop:-

function handleSelChange(){
var opts = this.options, disable = true;
var frmEls = this.form.elements, c = opts.length;
while(
(c--)&&
(
(!opts[c].selected)||
(
(opts[c].value != "2")||
(disable = false)
)
)
);
frmEls['boo'].disabled = disable;
frmEls['goo'].disabled = disable;
}

Richard.
 
F

Forti2ude

Richard, One other question: Is there a way to do it without an initial body ONLOAD?


Richard Cornford said:
Forti2ude said:
Richard, this satisfies my requirements. Thank you!
To everyone else, I also thank you. Very informative.
<snip>

Drat, now I have to own up to the mistake. ;) That line should be:-

(frmEl = (frmEl.elements||frmEl)) &&

The - frm - identifier was left over from an earlier revision.

It also occurred to me afterwards that the - for - could be a - while -
loop:-

function handleSelChange(){
var opts = this.options, disable = true;
var frmEls = this.form.elements, c = opts.length;
while(
(c--)&&
(
(!opts[c].selected)||
(
(opts[c].value != "2")||
(disable = false)
)
)
);
frmEls['boo'].disabled = disable;
frmEls['goo'].disabled = disable;
}

Richard.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,483
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top