SitePoint Sponsor

User Tag List

Results 1 to 5 of 5
  1. #1
    SitePoint Addict
    Join Date
    Dec 2010
    Posts
    227
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    Change label color on input focus

    Hi,

    Here's a sample form:

    Code:
    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
    <html>
    <head>
    <title>Sample Form</title>
    </head>
    <body>
    <form action="#">
    <label for="fname">First name</label><input type="text" id="fname">
    <br>
    <label for="lname">Last name</label><input type="text" id="lname">
    </form>
    </body>
    </html>
    I wonder how I can change the label color when I focus/tab on its text filed? How can I do it through JavaScript if CSS doesn't work here?

    Thanks in advance!
    Mike

  2. #2
    From space with love silver trophy
    SpacePhoenix's Avatar
    Join Date
    May 2007
    Location
    Poole, UK
    Posts
    5,068
    Mentioned
    103 Post(s)
    Tagged
    0 Thread(s)
    It can be done with css using http://reference.sitepoint.com/css/pseudoclass-focus but not all versions of the browsers will support that. Try and do it with css if you can incase the end user has javascript disabled
    Community Team Advisor
    Forum Guidelines: Posting FAQ Signatures FAQ Self Promotion FAQ
    Help the Mods: What's Fluff? Report Fluff/Spam to a Moderator

  3. #3
    SitePoint Addict
    Join Date
    Dec 2010
    Posts
    227
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by SpacePhoenix View Post
    It can be done with css using http://reference.sitepoint.com/css/pseudoclass-focus but not all versions of the browsers will support that. Try and do it with css if you can incase the end user has javascript disabled
    According to your reference:
    It can apply to a form control
    But I'm going to style the label when its corresponding input gets focus.

  4. #4
    Unobtrusively zen silver trophybronze trophy
    paul_wilkins's Avatar
    Join Date
    Jan 2007
    Location
    Christchurch, New Zealand
    Posts
    14,729
    Mentioned
    104 Post(s)
    Tagged
    4 Thread(s)
    Let's go with your currently existing code.

    We place the script at the end of the body, just before the </body> tag

    Code html4strict:
        </form>
        ...
        <script src="script.js"></script>
    </body>
    </html>

    When the script runs, you want to assign a CSS class to the label, to give it a background color:

    Code CSS:
    .focused {
        background-color: #00FFFF;
    }

    The script adds an onclick event listener to each input field, so that the inputFocusHandler script can handle the label class name.

    Code javascript:
    var form = document.getElementById('personalInfo'),
        i;
    for (i = 0; i < form.elements.length; i += 1) {
        if (form.elements[i].nodeName === 'INPUT') {
            form.elements[i].onfocus = inputFocusHandler;
        }
    }

    How the labelFocusHandler function works is to check that an input field was clicked on, after which it passes that input field on to the setLabelFocusWithInput function.

    The inputFocusHandler function gets the label field and adds the "focused" class name to it. Then when someone leaves the input field (that's the blur event) the class name is removed from the label field.

    Code javascript:
    function inputFocusHandler() {
        var label = searchUpForTagName(this, 'label');
        label.className = 'focused';
     
        this.onblur = function () {
            label.className = '';
        };
    }

    Notice how these functions are all nice and small, and each handle just one main concern.

    That searchUpForTagName function is where things start to get a bit more complex. We could just search the previous siblings and be done with it, but a preferred style to use with form labels is with a nested label:

    Code javascript:
    <label>
        First name
        <input type="text" name="fname">
    </label>

    So, we should go up the previous siblings of the input field looking for the label, and when we hit the top we should go to its parent, and then keep on looking up.
    We can do that in two stages, where we check if any previous siblings match, and if not go to the parent and keep on checking. If we end up at the body element, what we were looking for isn't there so we should just return without having found anything.

    Code javascript:
    function searchUpForTagName(field, tagName) {
        tagName = tagName.toUpperCase();
     
        // first check the previous siblings
        field = searchPreviousSiblings(field, tagName);
     
        while (field && field.nodeName !== tagName) {
            if (field.parentNode.nodeName === 'BODY') {
                return;
            }
            // then check the parent and its previous siblings
            field = field.parentNode;
            if (field.nodeName !== tagName) {
                field = searchPreviousSiblings(field.parentNode, tagName);
            }
        }
        return field;
    }

    Checking the previousSiblings is relatively straight forward too. We just check if a previous sibling exists before checking if it's what we want:

    Code javascript:
    function searchPreviousSiblings(fromElement, tagName) {
        var prevElement = fromElement;
        tagName = tagName.toUpperCase();
     
        if (!prevElement.previousSibling) {
            return;
        }
        prevElement = fromElement.previousSibling;
        while (prevElement && prevElement.nodeName !== tagName) {
            if (!prevElement.previousSibling) {
                return prevElement;
            }
            prevElement = prevElement.previousSibling;
        }
        return prevElement;
    }

    And so, to change the label color on input focus, tends to need the following code for it to be done properly:

    Code javascript:
    function searchPreviousSiblings(fromElement, tagName) {
        var prevElement = fromElement;
        tagName = tagName.toUpperCase();
     
        if (!prevElement.previousSibling) {
            return;
        }
        prevElement = fromElement.previousSibling;
        while (prevElement && prevElement.nodeName !== tagName) {
            if (!prevElement.previousSibling) {
                return prevElement;
            }
            prevElement = prevElement.previousSibling;
        }
        return prevElement;
    }
     
    function searchUpForTagName(field, tagName) {
        tagName = tagName.toUpperCase();
     
        // first check the previous siblings
        field = searchPreviousSiblings(field, tagName);
     
        while (field && field.nodeName !== tagName) {
            if (field.parentNode.nodeName === 'BODY') {
                return;
            }
            // then check the parent and its previous siblings
            field = field.parentNode;
            if (field.nodeName !== tagName) {
                field = searchPreviousSiblings(field.parentNode, tagName);
            }
        }
        return field;
    }
     
    function inputFocusHandler() {
        var label = searchUpForTagName(this, 'label');
        label.className = 'focused';
     
        this.onblur = function () {
            label.className = '';
        };
    }
     
    var form = document.getElementById('personalInfo'),
        i;
    for (i = 0; i < form.elements.length; i += 1) {
        if (form.elements[i].nodeName === 'INPUT') {
            form.elements[i].onfocus = inputFocusHandler;
        }
    }
    Programming Group Advisor
    Reference: JavaScript, Quirksmode Validate: HTML Validation, JSLint
    Car is to Carpet as Java is to JavaScript

  5. #5
    SitePoint Addict
    Join Date
    Dec 2010
    Posts
    227
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Dear Paul,

    I appreciate your time and educational notes. Thank you!


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
  •