Tag: css

Jericho Selector, ou jQuery para Java

CSS3

É com grande satisfação que venho anunciar a publicação da primeira versão estável (stable release) da biblioteca Jericho Selector.

O Jericho Selector é uma extensão para a conhecida biblioteca de leitura e manipulação de HTML Jericho HTML Parser que permite selecionar elementos de um documento HTML ao estilo do jQuery, ou seja, utilizando seletores CSS.

Por quê Jericho? Diferente do jsoup, por exemplo, ele permite alterar documents HTML mantendo a formatação original. Outras bibliotecas reescrevem o documento inteiro. De qualquer forma, eu gosto de ter opções! 😉

Jericho Selector é totalmente livre, sob a licença MIT.

Como usar

O Jericho Selector está disponível no Repositório Central do Maven, então basta configurar o seu projeto com a seguinte dependência:

<dependency>
    <groupId>br.com.starcode.jerichoselector</groupId>
    <artifactId>jericho-selector</artifactId>
    <version>1.0.1-RELEASE</version>
</dependency>

Depois, faça a importação do método estático $ que pode ser usado como ponto de entrada para uso do Jericho Selector:

import static br.com.starcode.jerichoselector.jerQuery.$;

Então você poderá realizar consultas da seguinte forma:

$(html, "p.my-text")

O que foi feito

Antes de iniciar a implementação do Jericho Selector, tive que implementar um interpretador (parser) completo de seletores CSS. Para isso, implementei outra biblioteca que chamei de parCCSer. Ela foi baseada na especificação oficial do W3C para CSS3 e cobre praticamente todos os aspectos da especificação, exceto alguns detalhes que se aplicariam apenas no contexto de um navegador e também algo relacionado a suporte de caracteres UTF-8. Ela também está sob a licença MIT.

O Jericho Selector então utiliza a árvore de objetos gerada pelo parCCser, assim como a API do Jericho HTML Parser para consultar os elementos de um documento HTML com base em um dado seletor.

Todas as implementações possuem cobertura em testes unitários de mais de 90% do código, sem contar os casos excepcionais que o plugin de cobertura não consegue analisar.

O que precisa ser feito

Nas próximas semanas pretendo adicionar ao Jericho Selector funcionalidades de uma API fluente, análogas ao jQuery, para que seja possível realizar operações com os elementos recuperados usando lambdas e outros recursos. Métodos como closest, parentsUntil, find, each são meus primeiros alvos.

Outro ponto a melhorar é o desempenho da biblioteca. Alguns seletores específicos podem ter sua execução otimizada utilizando cache ou métodos específicos do Jericho HTML Parser como getAllElementsByClass.

O que você pode fazer

Reporte qualquer problema e sugira novas funcionalidades!

Código-fonte

Confira o código e maiores detalhes na minha página do GitHub:

https://github.com/utluiz/jericho-selector/

Entenda como Zebrar uma tabela com CSS

Colorir alternadamente as linhas de uma tabela é um requisito comum. A abordagem mais comum é usar um código personalizado na view para adicionar estilos alternados. No entanto, é possível fazer isso sem o uso de uma linguagem de back-end como Java, PHP ou .Net.

CSS 3

Podemos usar estilos CSS selecionando os elementos pares e ímpares, como no seguinte exemplo:

/* linhas pares (even) */
.tabela tbody tr:nth-child(even) {
    background-color: #CCC;
}
/* linhas ímpares (odd) */
.tabela tbody tr:nth-child(odd) {
    background-color: #FFF;
}

Continuando com o exemplo, agora só precisamos adicionar a classe tabela ao elemento <table> no HTML:

<table class="tabela">
    <thead>
        ....
    </thead>
    <tbody>
        ....
    </tbody>
</table>

Veja um exemplo funcional no Jsfiddle!

Que bruxaria é essa?

Para quem não conhece a sintaxe do CSS, ou nem sabe que tipo de tecnologia é essa, trata-se de um tipo de linguagem para aplicar primariamente estilos visuais nos elementos de uma página web.

Considere o seguinte exemplo:

seletor {
    atributo1: valor1;
    atributo2: valor2;
}

Esta é a estrutura de uma regra (rule) do CSS. Regras são compostas pelas seguintes partes:

  • Seletor: define quais elementos serão afetados pela regra.
  • Atributo: especifica qual atributo será afetado. Podem haver vários atributos por regra.
  • Valor: o respectivo valor de cada atributo.

Um seletor que começa com um ponto (.), como em .tabela, chama-se seletor de classes. Ele diz ao navegador para aplicar a regra aos elementos que possuem o atributo class com a respectiva classe, como em class="tabela". Um elemento pode conter várias classes, cujos nomes devem ser separados por espaços em branco, como em class="tabela outra-classe".

Voltemos agora ao exemplo do tópico anterior. O seletor.tabela tbody tr:nth-child(even) primeiramente seleciona elementos que contém o atributo class="tabela".

Em seguida, encontramos o trecho tbody. Este é um seletor de tag, isto é, ele seleciona as tags <tbody>, que define o corpo da tabela, de forma que não zebramos o título da mesma. Como isso vem depois de .tabela e é separado por um espaço em branco, incluiremos todos os elementos <tbody> filhos do elemento com class="tabela". O próximo trecho é tr, que seleciona todos os elementos <tr> filhos do elemento <tbody>. Note que, se houver uma tabela dentro de outra, as linhas da tabela mais interna também serão afetadas. Se quiséssemos especificar a seleção apenas dos filhos diretos, poderíamos usar o caractere maior (>), como em .tabela > tbody > tr.

O seletor tr é seguido de um caractere de dois pontos (:). Este é um pseudo-seletor. Ele altera o seletor anterior. Nesse caso o pseudo-seletor nth-child() permite especificar quais elementos do conjunto total de tags <tr> serão realmente incluídos. Dentro do parêntesis, poderíamos especificar um índice numérico. Por exemplo, tr:nth-child(5) iria selecionar apenas a quinta linha da tabela. Porém, usamos os valores especiais odd e even para definir índices ímpares e pares, respectivamente.

Finalmente, aplicamos a cor #CCC (um cinza claro) ao atributo background-color (cor de fundo) às linhas pares. Depois, aplicamos a cor #FFF (branco, em hexadecimal) como cor de fundo das linhas ímpares. Note que o valor #FFF é uma abreviação para #FFFFFF. Na versão com 6 letras, cada dupla de bytes representam uma cor do RGB (Red, Green, Blue).

Ufa! Entendeu? 😉

Se você lê Inglês e quer se aprofundar, recomendo a referência da fundação Mozilla.

Compatibilidade com navegadores antigos

A solução em CSS é muito legal, mas o seletor nth-child não vai funcionar no Internet Explorer 6, 7 e 8. Se precisar manter a compatibilidade com essas versões do navegador, uma alternativa é usar jQuery. O jQuery simula seletores mais novos mesmo em navegadores antigos através de código Javascript.

O seguinte trecho de código aplica a coloração em linhas ímpares e pares logo após o carregamento da página:

$(document).ready(function() {
    //linhas pares, iniciando em zero
    $('.tabela tbody tr:even').css('background-color', '#FFF'); 
    //linhas ímpares iniciando em zero
    $('.tabela tbody tr:odd').css('background-color', '#CCC'); 
});

Note que inverti odd e even. Isso é porque a versão CSS do seletor usa índices baseados em 1 (1, 2, 3, …, N), enquanto a versão jQuery usa índices de vetores Javascript, que são baseados em 0 (0, 1, 2, …, N – 1).

Veja o exemplo funcional da versão em Javascript no Jsfiddle!


Este artigo foi baseado na minha resposta no StackOverflow em Português!

Como desabilitar campos em sistemas web

Quando lidamos com sistemas web, é frequente a necessidade de desabilitarmos algum campo na página, com a finalidade de impedir a alteração por parte do usuário.

O problema é que o navegador não envia campos desabilitados com disabled na submissão do formulário. Esta característica comumente deixa os novatos atordoados.

Solução: readonly

Uma solução é usarmos o atributo readonly, porém existem efeitos colaterais:

  • Se for um campo de texto, o usuário poderá selecionar e copiar o conteúdo, o que pode ser uma vantagem em alguns casos.
  • Além disso, os estilos do campo permanecerão os originais, isto é, o usuário poderá não perceber que se trata de um campo somente-leitura.

Para contornar o segundo ponto e dar feedback visual para o usuário, adicione um estilo para manter a usabilidade, por exemplo, deixando o fundo da caixa um pouco acinzentado.

Exemplo com CSS inline:

<input type="text" value="Valor fixo" 
    style="background: #EEE; cursor: not-allowed; color: #777"
    readonly />

Exemplo com uma classe CSS:

.desabilitado {
    background: #EEE; 
    cursor: not-allowed; 
    color: #777;
}

<input type="text" value="Valor fixo 2" class="desabilitado" readonly />

Veja o exemplo funcional do código acima no jsfiddle.

Considerações de segurança

Alguém pode argumentar que desabilitar campos na tela não é uma boa prática do ponto de vista de Segurança da Informação, pois hoje um usuário pode facilmente burlar essa limitação através da Ferramenta do Desenvolvedor (F12), alterando as propriedades do campo. Isso está correto, em parte.

O importante é entender que a necessidade de desabilitar campos é parte essencial do funcionamento dos sistemas. Não é seu objetivo garantir a segurança da informação daquele campo.

Este artigo tem por objetivo auxiliar o desenvolvedor front-end com um elemento puramente visual e não isenta as validações necessárias no back-end.

Entendido!?

Este artigo foi baseado na minha resposta no StackOverflow em Português!

Creative Commons O blog State of the Art de Luiz Ricardo é licenciado sob uma Licença Creative Commons. Copie, compartihe e modifique, apenas cite a fonte.