Textarea visibility based on dropdown selection

Hi everyone!

I have a form which has a dropdown menu on it. The last option on the menu “other”. When "other is clicked, I would like a textarea to become visible, so that the user can enter the new information. Does anyone know how I might do this?

I am very new to javascript, so any help would be greatly appreciated. Thank you :D.

Here is the html for the form:


Union: <select name="union" id="union">
<option value="choose">Choose One</option>
<option value="ibew">International Brotherhood of Electrical Workers</option>
<option value="ibt">International Brotherhood of Teamsters</option>
<option value="ila">International Longshoremen's Association</option>
<option value="ibb">International Brotherhood of Boilermakers</option>
<option value="iuec">International Union of Elevator Constructors</option>
<option value="iuoe">International Union of Operating Engineers</option>
<option value="iw">Iron Workers</option>
<option value="liuna">Laborers International Union of North America</option>
<option value="op">Operative Plasterers' and Cement Masons' International Association</option>
<option value="other">Other Union...</option>
</select>


Attach an onchange event on to the select field, and whenever it changes, check if it’s set to that other field and if so, reveal the textarea.


<textarea id="otherUnion"></textarea>

Place this script at the end of the body, just before the </body> tag.


var union = document.getElementById('union');
union.onchange = checkOtherUnion;
union.onchange();

function checkOtherUnion() {
    var union = this;
    var otherUnion = document.getElementById('otherUnion');
    if (union.options[union.selectedIndex].value === 'other') {
        otherUnion.style.display = '';
    } else {
        otherUnion.style.display = 'none';
    }
}

ok, so I placed the textarea just after the drop down in the html, and the JS script just before the </body> tag, but the textarea is there no matter what the selection is.

I must be making some stupid little error, but I can’t seem to make it work. (here I go again) :confused:

I have a few questions though.

  1. Why is the script before the </body> tag? I thought scripts were usually placed in the <head> section.

  2. In the opening <script> tag, should I put a specific JS version for the language? If so, which one?

Thanks once again for your time and assistance. One of these days I will finally undersand javascript. (I hope):smiley:

~ Lauren

I suspect that the stupid little error is my own. That being, do not invoke the function when assigning it to an event.

Change the commented out line to the one that follows it, and it’ll work fine.


//union.onchange = checkOtherUnion();
union.onchange = checkOtherUnion;

Fire away.

That has been a common practice, however several years ago some best practices to speed up your web site were published by Yahoo, including some for javascript, one of which is to [URL=“http://developer.yahoo.com/performance/rules.html#js_bottom”]put scripts at the bottom.

Not only does this speed up the loading of the page, but you can easily attach events to page elements without the slowness of using onload, or the complexity of using more advanced dom-ready techniques.

No version is required. That was a poor idea and was replaced by using a type declaration, such as the following:


<script type="text/javascript" src="script.js"> </script>

Note however some details:

The text/javascript type was deprecated in 2006, in favour of application/javascript. Internet Explorer fails to understand this though, and will refuse to run the code. This is why it’s better to either stay with the deprecated type, or because browsers default to javascript, to have no type specified there at all.

Secondly, html validators are working on standards from before 2006, so they will complain if no type is specified. Even though the type is ignored when using an external script file (with the src attribute) you need to have one there to keep validators happy.

Don’t stop asking questions. There is a lot of misinformation out there about how to do things. Some of it is historical to such a degree that it’s completely unrelated to reality anymore. Other parts of it are a matter of there being multiple ways to achieve the same objective, but often with different ease of use/maintenance/security issues involved.

So please, keep on asking questions. Rest assured that you’re unlikely to be put wrong here, due in large part to the active community of users here who all help out as need be.

Thanks so much! It worked! :smiley:

Can I do this the same way for another drop down on the same form, as long as I change the id’s? Also, can I put this in an external sheet with a function for each option that needs an onChange event?

I hope that made sense. :confused:

Yes, that will be quite easy. I’m going to do this backwards.

First there’s the show function which accepts one or two arguments. The first argument is the element to show. The second argument is optional. If present, it determines if the element is to be shown or not. This helps to prevent the need for extra logic to determine whether to call a separate show or a hide function.


function show(el, state) {
	if (state === undefined) {
		state = true;
	}
    if (state === true) {
		el.style.display = '';
    } else {
        el.style.display = 'none';
    }
}

Note: a better practice than changing the display value is to include the hasClass, addClass and removeClass functions which allows you to easily add or remove a class name of ‘hidden’ on the element, for which you will also have a css declaration for ‘hidden’ that sets the display to none.

Next up is how we’re going to keep track of the different options that are going to be monitored. Each select field could have several options, that when selected could each trigger different elements to be shown. While it’s possible to use a global array to store this information, it’s better to keep the info closer to where it’s being used.

What we can do is to add a ‘check’ object on to the element and within that check object we can set some properties, in this case they would be the value of the option and be associated to the element that will be shown.

In JSON format it would look like this:

{
    'check': {
        'liuna': laborersDetails,
        'other': otherUnion
    }
}

This means that the select element now contains all of the information that it need to know about. Whenever the select element is changed, we can loop through each of the options that need to be checked, and show or hide them where required.


function enableIfSelected() {
	var select = this,
		optionValue = select.options[select.selectedIndex].value,
		option,
		el;
	for (option in select.check) {
		if (select.check.hasOwnProperty(option)) {
			el = select.check[option];
			show(el, (option === optionValue));
		}
	}
}

The attachEnableIfSelected function adds the enableIfSelected function to a select field, but we also need to perform a couple of extra steps. First we should create the check object if it’s not already there, and then add to that check object the information that we’ll need for this option and its related element to be displayed. After the select field has its onchange event assigned to the enableIfSelected function, we’ll activate that event straight away which will hide the related element because it’s not currently selected.


function attachEnableIfSelected(select, value, id) {
	select.check = select.check || {};
	select.check[value] = document.getElementById(id);
	select.onchange = enableIfSelected;
	select.onchange();
}

Finally, we kick things off by specifying for which option we want to show a certain element. Because it’s a good practice to use form element names where possible, this part uses only one id attribute on the form itself, from where we can gain access to all of the other form element via their element names.

This example shows us attaching two elements on to a select elements values.


var form = document.getElementById('myForm'),
	union = form.elements.union;
attachEnableIfSelected(union, 'liuna', 'laborersDetails');
attachEnableIfSelected(union, 'other', 'otherUnion');

Here is the full script code:


function show(el, state) {
	if (state === undefined) {
		state = true;
	}
    if (state === true) {
		el.style.display = '';
    } else {
        el.style.display = 'none';
    }
}
function enableIfSelected() {
	var select = this,
		optionValue = select.options[select.selectedIndex].value,
		option,
		el;
	for (option in select.check) {
		if (select.check.hasOwnProperty(option)) {
			el = select.check[option];
			show(el, (option === optionValue));
		}
	}
}
function attachEnableIfSelected(select, value, id) {
	select.check = select.check || {};
	select.check[value] = document.getElementById(id);
	select.onchange = enableIfSelected;
	select.onchange();
}

var form = document.getElementById('myForm'),
	union = form.elements.union;
attachEnableIfSelected(union, 'liuna', 'laborersDetails');
attachEnableIfSelected(union, 'other', 'otherUnion');

Thank you. You have really outdone yourself. I really appreciate all your help. I am going to get to work right away trying understand this and work it into my code properly. I honestly don’t know what I would do without you, I probably would have given up on javascript by now :). I’ll let you know how it goes or, more likely, be back with more questions. Thanks again! :slight_smile:

~ Lauren