quarta-feira, 11 de dezembro de 2013

Destaque (highlight) do texto filtrado na coluna do Primefaces DataTable


Neste post vou mostrar como destacar na coluna do dataTable do Primefaces o texto que o usuário digita no filtro. São 5 passos bem simples, mostrados a seguir:

i) Criar no managed bean o método removeAcentos, como foi mostrado no post anterior.

ii) Fazer um binding da tabela:

1. <p:dataTable id="Tabela"
2.                              binding="#{controlador.tabela}"


1.     private DataTable tabela;
2. 
3.     public DataTable getTabela() {
4.         return tabela;
5.     }
6. 
7.     public void setTabela(DataTable tabela) {
8.         this.tabela = tabela;
9.     }

iii) Chamar um método para retornar o texto destacado, e usar escape="false":

1. <p:column headerText="Título"
2.            filterBy="#{registro.titulo}#{controlador.removeAcentos(registro.titulo)}"
3.            filterMatchMode="contains" >
4.            <h:outputText value="#{controlador.highlight(registro.titulo,'titulo}#{controlador.removeAcentos(registro.titulo)')}"
5.                            escape="false" />
6. </p:column>

O segundo parâmetro do método é o conteúdo do filterBy sem o identificador inicial e sem a chave final (ou seja, usar somente a parte destacada em verde, ignorando as partes vermelhas):

 #{registro.   titulo}#{controlador.removeAcentos(registro.titulo)    }

Este comportamento é do médoto getFilters da tabela, como poderemos ver posteriormente no quinto passo.

iv) Criar, no managed bean, o método para montar o texto destacado:

1.     public String buildHighlight(String filtro, String texto) {
2.         String retorno = "";
3.         Integer posicao = 0, tam = filtro.length();
4.         while (true) {
5.             if (posicao > texto.length()) {
6.                 break;
7.             }
8.             if ((texto.length() - posicao) < tam) {
9.                 retorno += StringUtils.substring(texto, posicao);
10.                 break;
11.             }
12.             if (removeAcentos(StringUtils.substring(texto, posicao, posicao + tam)).equalsIgnoreCase(removeAcentos(filtro))) {
13.                 retorno += <span style="color: red;'>" + StringUtils.substring(texto, posicao, posicao + tam) + "</span>";
14.                 posicao += tam;
15.             } else {
16.                 retorno += StringUtils.substring(texto, posicao, posicao + 1);
17.                 posicao++;
18.             }
19.         }
20.         return retorno;
21.     }

v) Criar, no managed bean, o método para obter o valor digitado e retornar o destaque:

1.     public String highlight(String texto, String filtro) {
2.         String retorno = "";
3.         if (texto != null) {
4.             Map<String, String> filtros = tabela.getFilters();
5.             String textoDigitado = filtros.get(filtro);
6.             if (textoDigitado != null) {
7.                 retorno = buildHighlight(textoDigitado, texto);
8.             } else {
9.                 return texto;
10.             }
11.         }
12.         return retorno;
13.     }

Veja um exemplo que filtra o texto "Aneis" (sem acentos!) e destaca o texto encontrado (com acentos!):


Este recurso foi implementado a partir da necessidade de visualizar mais facilmente palavras que são digitadas sem acento e que aparecem no texto da coluna com acento. Quando as palavras são bem específicas, a visualização é mais fácil, mas quando são palavras pequenas e o texto da coluna tem várias linhas, o destaque mostrado acima é essencial.

3 comentários:

  1. Este comentário foi removido pelo autor.

    ResponderExcluir
  2. StringUtils é classe de que pacote? qual será importado ao projeto?

    ResponderExcluir
  3. Olá Roselito, StringUtils é classe de qual pacote? Qual será importado ao meu projeto?

    ResponderExcluir