2
\$\begingroup\$

I have a form and need to be able to highlight/decorate fields as they gain focus (change their background color, border). I'm also decorating their corresponding 'labels'.

All works fine where it needs to: FF, Safari, IE 7, 8 and 9

Problem 1 cropped up with IE7 and changing background color of drop down box. There I had to resort to plain old JS to access the element and use 'onfocusin' and 'onfocusout' events otherwise it'd take 2 clicks to use the field.

Problem 2 was with Safari and how it handles 'focus' event with radio buttons. For that I'm using 'mouseenter' and 'mouseleave' events to change the color of their 'labels'.

Is there a cleaner way of doing this? The caveats are I have no control of the HTML whatsoever and I can't use anything other than jQuery 1.4.3 That's all dictated by content management system I must work with.

Here's a complete 99.9% 'production' code example: http://jsfiddle.net/HenriPablo/YvDPa/3/

Script in question:

$(document).ready( function(){

    /* PROFILE PAGE ONLY -> get rid of separator border on shipping addres block when editing any of the shipping addresses */
    if( $('#formShippingAddress').length > 0 ){
        $( 'table#block\\.crmshipping tbody tr td.block\\.crmshipping\\.text' ).css('border','none');
    }

    /* highlight input field labels when input field has focus */
    /* see if event bubble - this is critical for handling decoration of select drop down boxes in IE7 */
    if( $.support.changeBubbles){

        var partialID = 'table[id^="page"]'
        var focusable = $( partialID + ' input[type="text"], ' + partialID + ' input[type="password"], ' + partialID + ' select, ' + partialID + ' input[type="checkbox"]' );
        var clickable = $( partialID + ' input[type="radio"]' );

        focusable.focus( function( ){   decorate( $(this) ); })     
        focusable.blur( function( ){ decorate( $(this) ); })

        clickable.mouseenter( function(){ decorate( $(this) ); })
        clickable.mouseleave( function(){ decorate( $(this) ); })

    } else { // bubbling support check

        var i, d = document.getElementsByTagName('select')  

        for( i in d ){
            d[i].onfocusin = function() { 
                this.style.backgroundColor = '#b4d5ec' 
                $(this).closest("td").prev().addClass('highlightLabel');
            }
            d[i].onfocusout= function() { 
                this.style.backgroundColor='#ffffff' 
                $(this).closest("td").prev().removeClass('highlightLabel');
            }
        } // for

        $('table[id^="page"] input' ).focus( function( ){
            decorate( $(this) )     
        })

        $('table[id^="page"] input').blur( function( ){ 
            decorate( $(this) );
        })      
    } // handle  IE7

    function decorate( elm ){
        elm.toggleClass('highlightField');
        elm.closest("td").prev().toggleClass('highlightLabel');
    } // decorator function
});

Many thanks in advance :-)

\$\endgroup\$
  • 1
    \$\begingroup\$ The "cleanest" and probably easiest way would be to use the CSS :focus selector: input:focus {background-color: red}, which is widely supported, except IE7 and earlier. \$\endgroup\$ – RoToRa Aug 16 '11 at 13:52
  • \$\begingroup\$ that would, but can't happen under circumstances \$\endgroup\$ – vector Aug 16 '11 at 16:22
2
\$\begingroup\$

I'm not quite sure if this will do quite what you want, but here is my rehashing of the code:

$(document).ready(function() {
    $('table[id^="block"] input, select').bind("focus blur", function() {
        var $this = $(this);
        $this.closest("td").prev().toggleClass('highlightLabel');
        $this.not("select").toggleClass('highlightField');
    });
});

You can see it in action here on jsFiddle.

As far as I can tell, the only thing I changed, behavior-wise, is that the select dropdown list does not have a background color when focused. IMO, it looks better that way, but you might prefer it with the background color.

It seems to work the same on all the browsers I tested, but let me know if it doesn't and I'll look at it and see if I can fix it.

| improve this answer | |
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.