Show fieldset in response to clicking a checkbox

Can this be done? Particularly with jQuery?

I want to keep a fieldset hidden with Javascript and slide it open when a user checks a box to indicate that this fieldset is relevant to them. I’m fairly sure that I have seen this done in some forms.

I have begun to look through the docs, tutorials and some of the plugins listed under “forms”, but I am not 100% sure exactly what to look for or exactly how I would use it if I found it.

Can anyone help?


<input type="checkbox" name="other">
<fieldset class="other">
    ...
</fieldset>


$(function () {
    $('fieldset.other').hide();
    $('input[name="other"]').click(function () {
        if (this.checked) {
            $('fieldset.other').show();
        } else {
            $('fieldset.other').hide();
        }
    });
});

Many thanks for that. That fitted my needs exactly.

Hi! The code given by you doesnt work somehow… Can you please post the full code asap…? Thanks.

I am trying to do the same thing using straight unobtrusive JavaScript instead of jQuery, but am having trouble.

The JavaScript I have so far:

window.onload = prepareForm();
function prepareForm(){
if(!document.getElementById) return false;
var non_member_checkbox = document.getElementById (“non_member”);
non_member_checkbox.onclick = showHide(‘priv_info’);
}

function showHide(id){
var element = document.getElementById(id);
element.style.display = (style.display == “none”)?“block”:“”;
}

Here’s some sample code:


<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
	<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
	<title>Test</title>
	<script src="http://jqueryjs.googlecode.com/files/jquery-1.3.1.min.js"> </script>
	<script type="text/javascript">
	$(function () {
	    $('fieldset.other').hide();
	    $('input[name="other"]').click(function () {
	        if (this.checked) {
	            $('fieldset.other').show();
	        } else {
	            $('fieldset.other').hide();
	        }
	    });
	});
	</script>
</head>

<body>
<form id="myForm">
	<input type="checkbox" name="other"> Other
	<fieldset class="other">
	    Other reason: <input type="text" name="otherReason">
	</fieldset>
</form>
</body>
</html>

The onclick part needs to refer to a function. When you invoke the function, the value “undefined” is returned from it. You don’t want that to be assigned to the onclick event.

Here’s how you assign a function that requires arguments.


non_member_checkbox.onclick = function () {
    showHide('priv_info');
}

The second problem is in this line:


element.style.display = (style.display == "none")?"block":"";

in which there are a couple of issues.

First of all, style.display doesn’t refer to anything, it needs to be element.style.display instead.

Second, the display property is being checked if it’s “none” so I can only presume that you’ve set that element to have a style of “none”. I’ll go in to more appropriate techniques shortly, but if the style is not “none” then it needs to be set to “none” and not “” as the above line was attempting.

So changing it to the following will make it work:


element.style.display = (element.style.display === "none") ? "block" : "none";

Now we have some code that works. My next post will get in to further improvements that should be made to it.

Here’s the test code:


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

<body>
<form id="myForm">
	<input type="checkbox" name="non_member" id="non_member"> Non-member
	<div id="priv_info" style="display: none">
	    Other reason: <input type="text" name="otherReason">
	</div>
</form>
<script type="text/javascript">
window.onload = prepareForm();
function prepareForm() {
	if (!document.getElementById) {
		return false;
	}
	var non_member_checkbox = document.getElementById("non_member"); 
	non_member_checkbox.onclick = function () {
		showHide('priv_info');
	}
}
function showHide(id) {
	var element = document.getElementById(id);
	element.style.display = (element.style.display === "none") ? "block" : "none";
}
</script>
</body>
</html>

A first improvement for this is to not use getElementById to get the form field. You should instead use the elements array of the form to access those elements. That way the id attribute doesn’t become mandatory on form fields.

Second, I’ll use a separate function called togglePrivInfo so that the onclick event can be assigned in an easier manner. The showHide function has also been renamed to toggle, for the sake of consistancy.

We can now remove the inline style to hide the “priv_info” section, because once the onclick event is assigned we can also activate the onclick event, which will hide that element for us when the page loads.

I’m also going to remove the block part from the toggle. Not all elements should be displayed as block, so if instead you set the display to an empty string, that element will return back to its default display type.

The ternary makes it quite a long line that’s somewhat difficult to intuit what’s happening, so I’ll split that into a couple of separate lines. One to work out which display type to use, and the other to set it.

Finally, instead of using the onload technique, because the script is running from the end of the body we can run the script straight away, which means that it will run a lot sooner than any onload technique can achieve.

Here’s the end result of all these updates:


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

<body>
<form id="myForm">
	<input type="checkbox" name="non_member"> Non-member
	<div id="priv_info">
	    Other reason: <input type="text" name="otherReason">
	</div>
</form>
<script type="text/javascript">
function prepareForm() {
	if (!document.getElementById) {
		return false;
	}
	var form = document.getElementById('myForm');
	non_member_checkbox = form.elements["non_member"]; 
	non_member_checkbox.onclick = togglePrivInfo;
	non_member_checkbox.onclick();
}
function togglePrivInfo() {
	toggle('priv_info');
}
function toggle(id) {
	var element = document.getElementById(id);
	var display = (element.style.display === 'none') ? '' : 'none';
	element.style.display = display;
}
prepareForm();
</script>
</body>
</html>

Thank you pmw57! The script you suggested works great. I’m just starting out with JavaScript so I really appreciate your suggestions and improvements as well.

I was hoping to have this script live in an external file, but when I tried linking to it, it stopped working. Should this script work as is when linked in an external file, or does it need more work?

Placing the script in an external file will be the cause of no problems at all, unless of course the wrong filename is being used to reference the script. It just needs to run from the end of the body, that is, being in the same relative location as the test code above.

Ah I had the link in the <head>. Works perfect when I moved it to the end of the <body>.

Thanks again!