Disable/Clear textbox when checkbox is selected

Hi genii, I have an input type set as text however I want this textbox to set to “Out Now” and greyed out (or do either of the two but both is preferable) when the user ticks on a separate checkbox. Can anyone help?

This is pretty basic JavaScript. Please show what you got so far and I will help you out.

Thank you for the reply, I found out the answer from here in the meantime :rolleyes:

Well that is pretty horrible code. Why is it so bad?

[list][]It has a slew of id values strewn about all over the place
[
]There are identical id’s! They’re called unique identifiers for a good reason
[]Some attributes aren’t lowercased, and are even inconsistant with each other
[
]presentational markup has been used, those breaks need to go
[*]the form elements aren’t even contained within fieldset tags or at least, block elements like a paragraph
[/list]
As for the scripting, it has scripting code mixed in with the content! You’ve no doubt been taught that CSS styles inline with the HTML is a bad thing, well scripting is also bad when inline with HTML. Keep the separation between the content, the presentation and the behaviour.

That will need to change completely, to be of any use. Yes it is possible for you to use that code but your page is going to be a lot worse off in the long run.

Here is that original code.


<form>
<INPUT type="checkbox" name="chk_all" checked onClick="select_all(this,'ID_')"> All<br>
<input type="checkbox" id="chk" name="ID_1" value="V1" checked onclick="update_disabled(this)" />
<input type="text" id="txtOther_dis" disabled="disabled" class="dis" name="Other_1" size="20"><br>
<input type="checkbox" id="chk" name="ID_2" value="V2" checked onclick="update_disabled(this)" />
<input type="text" id="txtOther_dis" disabled="disabled" class="dis" name="Other_2" size="20"><br>
<input type="checkbox" id="chk" name="ID_3" value="V3" checked onclick="update_disabled(this)" />
<input type="text" id="txtOther_dis" disabled="disabled" class="dis" name="Other_3" size="20"><br>
</form>

Let’s cut this right back.

[list][]Get rid of all the id elements and have one only on the form itself. No others need to be used.
[
]Sanitise the tag and attribute names
[]Remove the disabled attribute, which will be set only from the script itself
[
]Remove the class name, which likewise will only be set from the script
[*]Remove the break tags, they shouldn’t be used in forms, and replace them with separate paragraphs. If you want less of a gap between the form paragraphs then that’s presentational, do it from CSS instead.[/list]


<form action="submit.php">
	<p><input type="checkbox"> <label>Check All</label></p>
	<p><input type="checkbox" name="checkbox1" value="value1">
	   <input type="text" name="text1"></p>
	<p><input type="checkbox" name="checkbox2" value="value2">
	   <input type="text" name="text2"></p>
	<p><input type="checkbox" name="checkbox3" value="value3">
	   <input type="text" name="text3"></p>
</form>

The first checkbox has no name because you don’t necessarily want to send it’s state to the server, just the changes that it makes to the other ones.

Now when you activate one of the text checkboxs, you want it to toggle the state of the textbox that’s beside it.

We will want an identifier on the form to make it easier for the script to find it, and a class name called “toggle” on each checkbox that we intend to use to toggle the input field. This is a good safety measure


<form id="myForm" action="submit.php">
	<p><input type="checkbox"> <label>Check All</label></p>
	<p><input type="checkbox" name="checkbox1" class="toggle" value="value1">
	   <input type="text" name="text1"></p>
	<p><input type="checkbox" name="checkbox2" class="toggle" value="value2">
	   <input type="text" name="text2"></p>
	<p><input type="checkbox" name="checkbox3" class="toggle" value="value3">
	   <input type="text" name="text3"></p>
</form>

The script follows in the next post.

This script gets loaded after the forms become available. The best way to do this is to place the script at the bottom of the page. That is also the best place to put scripts for page loading speed and optimization.

With that one id value on the form to help us find it, we can easily search the form and add an event to the appropriate checkboxes.


// get the form input elements
var form = document.getElementById('myForm');
var inputs = form.getElementsByTagName('input');
// walk through each input element
for (var i = 0; i < inputs.length; i++) {
    // if it's a toggle element, assign an onclick event to it
    if (inputs[i].className.match(/\\btoggle\\b/)) {
        inputs[i].onclick = toggleInput;
    }
}

So that’s nice and easy. You walk through each form element and if it has the “toggle” classname, it gets an event attached to it.

The only bit that might need further explaining is the match part. That’s using a regular expression to find the word “toggle”. The regular expression is demarked with forward slashes (/…/) and the \b in there ensures that there is a word break, either a gap of some kind or the start/end of the string, which effectively means that it won’t match “toggled” but only “toggle”. You can also have multiple class names on that element, such as “toggle required” without causing any problems.

So now, when the checkbox is pressed, it calls a function called toggleInput(). Because the traditional event registration was used, the this keyword will refer to the element that was clicked. If the onclick attribute was used instead, we would be forced to pass the this keyword as an argument to to the function instead, and we might also be tempted to pass a target id name.

Here is an example of how we do not want to write code.


<input type="checkbox" name="checkbox2" class="toggle" value="value2" onclick="toggleInput(this, 'idOfInputToToggle')">

As I was saying we do not want to code that way. Instead, the this keyword is automatically passed when the event is assigned from javascript, and we can easily use DOM traversal techniques to find the input element that we want to toggle.

When the field gets disabled, IE doesn’t provide much visual feedback on whether something is disabled or not, so we’ll also add a class name of “disabled” when appropriate.


.disabled {
    background: lightgrey;
}

Note: IE is funny. You have to spell it “lightgrey” or “gray”. Other variations of spelling grey/gray aren’t accepted. It would have been a lot better to use input[disabled=“disabled”] so that we don’t have to set the class name from the script, but IE can’t get that right either.

Anyway, what follows is the workhorse of our code. It walks through each element after the checked one, and enables or disables the first appropriate input that it comes across.


function toggleInput() {
    // start searching from the clicked element. The el variable
    // gets changed as we go from one element to the next.
    var el = this;
    // stop searching when we run out of elements
    while (el.nextSibling) {
        el = el.nextSibling;
        // look for an appropriate input field
        if (el.nodeName === 'INPUT' && el.type === 'text') {
            if (this.checked) {
                // Settings when checked
                el.value = 'Out Now';
                el.className = 'disabled';
                el.setAttribute('disabled', 'disabled');
            } else {
                // settings when unchecked
                el.value = '';
                el.className = '';
                el.removeAttribute('disabled');
            }
            // stop searching after the first input has been found
            break;
        }
    }
}

Thank you pmw57 for taking the time to write such a helpful and educational response. I’ve updated my code accordingly :slight_smile: