# jQuery and cross browser input fields focus handling

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 :-)

• 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. – RoToRa Aug 16 '11 at 13:52
• that would, but can't happen under circumstances – vector Aug 16 '11 at 16:22

## 1 Answer

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.