SitePoint Sponsor

User Tag List

Results 1 to 6 of 6
  1. #1
    SitePoint Addict Bravogolf's Avatar
    Join Date
    Aug 2004
    Location
    All over really :)
    Posts
    205
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    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?

  2. #2
    SitePoint Wizard Pepejeria's Avatar
    Join Date
    Jan 2005
    Location
    Too far up north
    Posts
    1,566
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    This is pretty basic JavaScript. Please show what you got so far and I will help you out.

  3. #3
    SitePoint Addict Bravogolf's Avatar
    Join Date
    Aug 2004
    Location
    All over really :)
    Posts
    205
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Thank you for the reply, I found out the answer from here in the meantime

  4. #4
    Unobtrusively zen silver trophybronze trophy
    paul_wilkins's Avatar
    Join Date
    Jan 2007
    Location
    Christchurch, New Zealand
    Posts
    14,526
    Mentioned
    83 Post(s)
    Tagged
    3 Thread(s)
    Well that is pretty horrible code. Why is it so bad?

    • 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

    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.

    Code html4strict:
    <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.
    • 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.


    Code html4strict:
    <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

    Code html4strict:
    <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.
    Last edited by paul_wilkins; Feb 25, 2008 at 12:38.
    Programming Group Advisor
    Reference: JavaScript, Quirksmode Validate: HTML Validation, JSLint
    Car is to Carpet as Java is to JavaScript

  5. #5
    Unobtrusively zen silver trophybronze trophy
    paul_wilkins's Avatar
    Join Date
    Jan 2007
    Location
    Christchurch, New Zealand
    Posts
    14,526
    Mentioned
    83 Post(s)
    Tagged
    3 Thread(s)
    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.

    Code javascript:
    // 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.

    Code html4strict:
    <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.

    Code css:
    .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.

    Code javascript:
    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;
            }
        }
    }
    Last edited by paul_wilkins; Feb 25, 2008 at 12:44.
    Programming Group Advisor
    Reference: JavaScript, Quirksmode Validate: HTML Validation, JSLint
    Car is to Carpet as Java is to JavaScript

  6. #6
    SitePoint Addict Bravogolf's Avatar
    Join Date
    Aug 2004
    Location
    All over really :)
    Posts
    205
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Thank you pmw57 for taking the time to write such a helpful and educational response. I've updated my code accordingly


Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •