Por uma questão de usabilidade e estética, é uma boa prática acrescentar algum tipo de feedback visual em formulários web para indicar o campo atualmente ativo (ou "focado"). Alguns navegadores (Safari / Opera) decidiram que é tão importante, que eles próprios implementaram esse tipo de funcionalidade por padrão aplicando uma borda azul em torno de elementos para marcá-los como ativos, tal como na Figura 1.

Exemplo de campo de texto padrão e com destaque

Figura 1: Exemplo de campo de texto padrão e com destaque

O procedimento é simples, principalmente se você já desenvolve web ou conhece conceitos de CSS e HTML. Para browsers que não sejam o Safari ou Opera, é possível usar CSS para implementar o estilo de foco no campo, através da pseudo-class :focus, tal como pode ser visto na Listagem 1.

Listagem 1: Exemplo de uso do CSS focus em um campo HTML

input:focus {
      background: blue;   /* azul*/
}

Essa é uma ótima estratégia, mas infelizmente existem alguns pontos negativos:

  • Não funciona em alguns browsers, a se dizer do Internet Explorer;
  • Isso funciona marcando apenas o campo em si, e desconsidera completamente a label e o espaço ao redor do mesmo.

O lado bom da situação é que existem algumas alternativas mais elegantes, dentre elas fazendo uso de JavaScript ou de bibliotecas JavaScript como jQuery. Analise então o código da Listagem 2, onde consta o mesmo modelo de formulário, porém com os campos de input e label dentro da div.

Listagem 2: Formulário exemplo com campos dentro da DIV

<form>
	<div class="campo-simples">
		<label for="Nome">Nome:</label>
		<input name="Nome" type="text"></input>
	</div>
	<div class=" campo-simples ">
		<label for="Email">Email:</label>
		<input name="Email" type="text"></input>
	</div>
</form>

A jQuery é uma biblioteca que trabalha com a leitura dos componentes HTML no DOM e implementação dos eventos através dos métodos disponíveis na API da mesma. Através disso, é possível identificar quando um campo de input de um formulário recebe o foco e implementar a regra CSS para que o campo seja marcado, consequentemente. A função ready é usada para configurar alguma coisa quando a página for inicializada (Listagem 3).

Listagem 3: Função ready para mapear o evento de foco no campo de input

$(document).ready(function(){
	$("input").focus(function() {
		....fazer alguma coisa....
	});
});

Essa é a parte legal da jQuery: poder acessar o componente pai do input, a div, para modificar o estilo da mesma. Tudo isso é possível por causa do mapeamento hierárquico que a jQuery faz no Document Object. O objetivo é aplicar uma única classe a essa mesma div quando o cursor entrar no foco do campo em questão. Veja na Listagem 4.

Listagem 4: Código de adição da classe de focoAtual

$(document).ready(function(){
	$("input").focus(function() {
		$(this).parent().addClass("focoAtual");
	});
});

E de tal forma, poder criar a classe CSS para o mesmo efeito (Listagem 5). Notar que a mesma deve ser criada dentro da tag style correspondente.

Listagem 5: Estilo CSS para foco do campo

div.focoAtual {
	background: #fdecb2;
}

O resultado pode ser visto na Figura 2.

Resultado do CSS no campo de input

Figura 2: Resultado do CSS no campo de input

Conforme você pode notar, o resultado saiu como planejado. Entretanto, existe um problema ao usar essa estratégia: após a classe CSS ser aplicada ao campo, a mesma continuará lá quando o mesmo campo perder o foco. Isso foge às expectativas de funcionalidade quando leva-se em consideração que o próximo campo que receber o foco também ficará marcado. Felizmente, a jQuery também encapsula o evento de blur que é o oposto do focus, ou seja, que é executado após o campo perder o foco. Veja na Listagem 6, como o código ficará.

Listagem 6: Adição do código de remoção da classe CSS

$(document).ready(function(){
	$("input").focus(function() {
		$(this).parent().addClass("focoAtual")
	});
	$("input").blur(function() {
		$(this).parent().removeClass("focoAtual")
	});
});

Não necessariamente é preciso especificar "focoAtual" na função removeClass, pois se você deixar em branco ele irá remover todas as classes, mas apenas no caso de se ter várias classes, pode deixar por isso mesmo.

Cada um dos quatro cantos é uma pequena div que necessita para ir para dentro de cada um dos divs wrapper de campo. Uma vez que todos eles são exatamente o mesmo e precisam estar dentro de cada div wrapper, vamos aplicá-las através da jQuery e evitar marcação repetida e desnecessária.

É possível fazer qualquer trecho de HTML em um objeto jQuery. Então que tal usar a função "appendTo" para colocá-lo dentro de cada div? Confira na Listagem 7.

Listagem 7: Uso da função appendTo

$('<div class="tl"></div><div class="tr"></div><div class="bl">
</div><div class="br"></div>').appendTo("div.campo-simples");

No CSS, estilize-o, mas deixe seus valores de exibição para "none" para que eles não apareçam até que seja preciso (Listagem 8).

Listagem 8: CSS para exibição das bordas

.tl {
	position: absolute;
	top: 0;
	left: 0;
	width: 10px;
	height: 10px;
	background: url(images/corner-topleft.jpg);
	display: none;
}
.tr {
	position: absolute;
	top: 0;
	right: 0;
	width: 10px;
	height: 10px;
	background: url(images/corner-topright.jpg);
	display: none;
}
.bl {
	position: absolute;
	bottom: 0;
	left: 0;
	width: 10px;
	height: 10px;
	background: url(images/corner-bottomleft.jpg);
	display: none;
}
.br {
	position: absolute;
	bottom: 0;
	right: 0;
	width: 10px;
	height: 10px;
	background: url(images/corner-bottomright.jpg);
	display: none;
}

Finalmente, implemente o código da Listagem 9 para que o jQuery consiga varrer o conteúdo do teu formulário e preencher com as respectivas cores de plano de fundo ao evento de foco.

Listagem 9: Codigo completo de adição das bordas

<script type="text/javascript" src="js/jquery.js"></script>
<script type="text/javascript">
	$(document).ready(function(){
		$("input").focus(function() {
			$(this)
				.parent()
					.addClass("focoAtual")
				.children("div")
					.toggle();
		});
		$("input").blur(function() {
			$(this)
				.parent()
					.removeClass("focoAtual")
				.children("div")
					.toggle();
		});
		$('<div class="tl"></div><div class="tr"></div><div class="bl"></div>
<div class="br"></div>').appendTo("div.campo-simples");
	});
</script>

Agora sim temos o resultado final completo esperado.