SitePoint Sponsor

User Tag List

Results 1 to 8 of 8
  1. #1
    SitePoint Addict
    Join Date
    Dec 2007
    Posts
    206
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    Checkbox-->Onclick-->Enable Text Input

    I have this
    Code html:
    <div class="checkgrp"><div class="chkfirst"><input class="chkbox" type="checkbox" name="check[]" value="Bed / Bath Size" onclick="enable('a')"/>Bed / Bath Size</div>
        <div class="chksecond">
    	<input class="checkinput" id="bedbath" type="text" name="a" /></div>

    with this javascript

    Code javascript:
    function enable(elm){
    document.forms[0][elm].disabled = false;
    }

    What I'm trying to do is have the textbox disabled unless the checkbox is checked, then the person can type into it. I know somethings wrong, but I don't know exactly what I'm lookin at since I dont know javascript at all

  2. #2
    Unobtrusively zen silver trophybronze trophy
    paul_wilkins's Avatar
    Join Date
    Jan 2007
    Location
    Christchurch, New Zealand
    Posts
    14,700
    Mentioned
    101 Post(s)
    Tagged
    4 Thread(s)
    The main trouble that I can see with how you're trying to change disabled property is that the element is disabled if the disabled property has anything other null or undefined. Even if it has a value of true or false, they will still be considered a value so it stays disabled. So instead, give the disabled property the value of null and all will be fine.

    I don't like the [0] reference for the form as it's very brittle and guaranteed to break when other forms are added before it. If the form has an identifer or a name, that would be more preferable than just using 0. document.forms['myform'] instead of document.forms[0]

    Code html4strict:
    <form name="myForm" action="...">

    Code javascript:
    // process event
    function toggle(elm, state){
        if (state == true) {
    		document.forms['myForm'][elm].disabled = null;
    	} else {
    		document.forms['myForm'][elm].disabled = 'disabled';
    	}
    }

    If the event is attached using inline event registration, the this keyword only refers to the window itself. However, if it is attached using traditional event registration via javascript, the this keyword then properly refers to the element that fired the event.

    Another benefit is that because the script isn't inline and is in a separate script file, it can be used across multiple pages, and if changes need to occur, you will need to change only the script itself and not multiple pages.

    So, let's get rid of that inline event attribute.

    Code html4strict:
    <input class="chkbox" type="checkbox" name="check[]" value="Bed / Bath Size" />Bed / Bath Size

    And attach the event using traditional event registration instead. This needs to be attached after the element is available, so we'll wait until the page has finished loading before attaching it.

    Code javascript:
    window.onload = function () {
        // attach event
        document.forms['myForm']['check[]'].onclick = function() {
            toggle('a', this.checked);
        };
    };

    The only thing left to be done is to make sure that the element is disabled when the page loads. If the checkbox is not ticked when the page is loaded, then you want the text area to be disabled as well. We should run the function when the page loads to be sure that things are set as they should be.

    Code javascript:
    window.onload = function () {
        // attach event
        document.forms['myForm']['check[]'].onclick = function() {
            toggle('a', this.checked);
        }
        // fire event
        document.forms['myForm']['check[]'].onclick();
    };

    Normally I wouldn't use the window.onload technique because it can be used only once. and there is a delay between the page being visible and the onload event firing. So instead of using window.onload, I prefer to place the script at the bottom of the body instead. This guarantees that the elements are available for use, and the scripts is run as soon as possible, long before the onload event gets triggered.

    Code javascript:
    // Instead of window.onload, we place the following at the bottom of the body instead
    // attach event
    document.forms['myForm']['check[]'].onclick = function() {
    	toggle('a', this.checked);
    }
    // fire event
    document.forms['myForm']['check[]'].onclick();

    Either way though, there's your solution for you, one that won't cause trouble if javascript isn't available either.
    Programming Group Advisor
    Reference: JavaScript, Quirksmode Validate: HTML Validation, JSLint
    Car is to Carpet as Java is to JavaScript

  3. #3
    Unobtrusively zen silver trophybronze trophy
    paul_wilkins's Avatar
    Join Date
    Jan 2007
    Location
    Christchurch, New Zealand
    Posts
    14,700
    Mentioned
    101 Post(s)
    Tagged
    4 Thread(s)
    There is only one more thing you may want to do and that's to add a style to it so that Internet Explorer users can visually see that it's disabled too.

    To do that you would have a disabled class

    Code css:
    .disabled {
        background: silver;
    }

    and change the element class when you toggle the disabled value.

    Code javascript:
    if (state == true) {
        document.forms['myForm'][elm].disabled = null;
        document.forms['myForm'][elm].className = '';
    } else {
    	document.forms['myForm'][elm].disabled = 'disabled';
    	document.forms['myForm'][elm].className = 'disabled';
    }

    and ... hang on, do you see the duplication there? If it occurs twice then it's time to think about improving it. Three times or more and it definately needs to be improved, so let's fix that.

    Code javascript:
    var el = document.forms['myForm'][elm];
    if (state == true) {
        el.disabled = null;
        el.className = '';
    } else {
        el.disabled = 'disabled';
        el.className = 'disabled';
    }

    That's better. What happens though if they already have class names on them? There are some fancy ways to deal with that but for now, we'll just save them aside when we change them and put them back afterwards.

    Code javascript:
    var el = document.forms['myForm'][elm];
    if (state == true) {
        el.disabled = null;
        el.className = el.oldClassName || '';
    } else {
        el.disabled = 'disabled';
        el.oldClassName = el.className;
        el.className = 'disabled';
    }

    And that's better, IE users can now visually see that the text field is disabled too.
    Programming Group Advisor
    Reference: JavaScript, Quirksmode Validate: HTML Validation, JSLint
    Car is to Carpet as Java is to JavaScript

  4. #4
    SitePoint Addict
    Join Date
    Dec 2007
    Posts
    206
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    thx! i havent tested it yet, but read thru all of it and I'll try it as soon as I can.. it does look a lil confusin but ill reply later on today after i test it out

  5. #5
    SitePoint Addict
    Join Date
    Dec 2007
    Posts
    206
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    quick question! whats traditional event registration?

  6. #6
    Unobtrusively zen silver trophybronze trophy
    paul_wilkins's Avatar
    Join Date
    Jan 2007
    Location
    Christchurch, New Zealand
    Posts
    14,700
    Mentioned
    101 Post(s)
    Tagged
    4 Thread(s)
    inline event registration is where you use an event attribute directly inline with the HTML code

    Code html4strict:
    <a id="myLink" href="link.html" onclick="doSomething(this)">Link</a>

    Traditional event registration is where there is no javascript in the HTML, and javascript itself registers the event.

    Code html4strict:
    <a id="myLink" href="link.html">Link</a>

    Code javascript:
    document.getElementById('myLink').onclick = doSomething;

    The benefit traditional event registration is that the this keyword references the element that fired the event, whereas with inline event registration the this keyword stays referenced to the window itself.

    See http://www.quirksmode.org/js/introevents.html for more details
    Programming Group Advisor
    Reference: JavaScript, Quirksmode Validate: HTML Validation, JSLint
    Car is to Carpet as Java is to JavaScript

  7. #7
    SitePoint Addict
    Join Date
    Dec 2007
    Posts
    206
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by pmw57 View Post


    Traditional event registration is where there is no javascript in the HTML, and javascript itself registers the event.

    Code html4strict:
    <a id="myLink" href="link.html">Link</a>

    Code javascript:
    document.getElementById('myLink').onclick = doSomething;

    The benefit traditional event registration is that the this keyword references the element that fired the event, whereas with inline event registration the this keyword stays referenced to the window itself.
    I looked at the external link and im still a little confused.. with the html part, since I'm using a text field input instead of an anchor do I name the inpue "myLink"?? and for the javascript part, does that go in the external javascript file that I link to or does it have to be on the page?

  8. #8
    Unobtrusively zen silver trophybronze trophy
    paul_wilkins's Avatar
    Join Date
    Jan 2007
    Location
    Christchurch, New Zealand
    Posts
    14,700
    Mentioned
    101 Post(s)
    Tagged
    4 Thread(s)
    The identifier "myLink" is an example one. You should use an identifier that best describes the element that is being identified.

    If it's only one input field then an identifier is a great way to target that element.

    Code html4strict:
    <label for="homephone">Home Phone Number</label>
    <input type="text" id="homephone" name="homephone" class="phone">

    Code javascript:
    document.getElementById('homephone').onchange = validate;

    If you want to apply an event on multiple input fields, you should use the element structure where you can, before resorting to multiple identifiers. While it's still possible to use individual identifiers, the code can get unweildy and difficult to manage.

    Code html4strict:
    <form id="comments" action="...">
    <p><label for="username">User name</label>
    <input type="text" id="username" name="username"></p>
    <p><label for="email">Email address</label>
    <input type="text" id="email" name="email" class="email"></p>
    <p><label for="message">Message</label>
    <input type="text" id="message" name="message"></p>	
    </form>

    Code javascript:
    // not good, as it gets very unweildy with 40 form elements
    document.getElementById('username').onchange = validate;
    document.getElementById('email').onchange = validate;
    document.getElementById('message').onchange = validate;

    So instead, target a higher-level element and use that to let you walk through the elements you need.

    Code javascript:
    // this is how it is more effectively done
    var comments = document.getElementById('comments');
    var inputs = comments.getElementsByTagName('input');
    for (var i = 0; i < inputs.length; i++) {
        if (inputs[i].type === 'text') {
    		inputs[i].onchange = validate;
    	}
    }

    Using the elements collection is also an excellent way to target form elements, especially when you're dealing specifically with form elements.

    Code javascript:
    // this is how it is more effectively done
    var comments = document.getElementById('comments');
    var els = comments.elements;
    for (var i = 0; i < els.length; i++) {
        if (els[i].type === 'text') {
    		els[i].onchange = validate;
    	}
    }
    Programming Group Advisor
    Reference: JavaScript, Quirksmode Validate: HTML Validation, JSLint
    Car is to Carpet as Java is to JavaScript


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
  •