Suporte a HTML5 com JSF 2.2
Aprenda a usar HTML5 em suas páginas com Pass-through Attributes e Elements do JSF 2.2
O HTML5 é provavelmente uma das palavras mais “fashions” e faladas no mundo do desenvolvimento Web atualmente. Esta fama não é à toa, pois novas funcionalidades e melhorias foram implementadas para facilitar a vida dos desenvolvedores Web. Por esse motivo, uma das principais melhorias no JSF 2.2 foi o suporte as novidades do HTML5, que acabou sendo chamada de HTML(5) Friendly Markup.
Os novos recursos do HTML5 podem tornar desnecessário a criação de componentes customizados e poupar o trabalho dos desenvolvedores. Em vez de criar novos componentes visuais, o suporte a HTML5 do JSF 2.2 permite o uso dos novos atributos e elementos do HTML5 diretamente nas páginas e nos componentes já existentes do JSF. Este suporte pode ser dividido em duas categorias:
- Pass Through Attributes;
- Pass Through Elements;
Dessa forma, o desenvolvedor passa a ter um maior controle sobre o HTML gerado. Além de poder usar os componentes JSF e os novos recursos do HTML5 como achar melhor.
Pass Through Attributes
Com o HTML5 novos atributos foram adicionados aos elementos existentes, como o atributo placeholder
, na qual é utilizado para definir um texto em um input
vazio. Enquanto outros atributos foram modificados, como o atributo type
do elemento input
, na qual agora suporta novos tipos, como email
, date
, datetime
e number
, por exemplo.
Fora isso, os custom data attributes (data-*) também são suportados por qualquer elemento da página, dessa forma é possível adicionar atributos customizados aos elementos HTML que não serão renderizados para o usuário final mas podem ser trabalhados via JavaScript.
O problema é que por questões de design não é possível usar atributos que não são suportados nativamente pelos componentes do JSF. Não podemos especificar atributos arbitrários nos componentes, pois eles serão ignorados pelo JSF ao renderizar o HTML. Para resolver isso, o JSF 2.2 trouxe o recurso chamado de Pass Through Attributes.
Podemos usar o recurso de pass through attributes de 4 maneiras diferentes, tanto nas páginas Facelets como programaticamente via código Java, como a seguir:
1. Namespace
A maneira mais simples de usar o recurso é através da nova namespace http://xmlns.jcp.org/jsf/passthrough . Com esta namespace, podemos passar atributos prefixados para os componentes. O seguinte exemplo mostra o componente h:inputText
com dois atributos nativos e dois pass-through attributes:
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://xmlns.jcp.org/jsf/html"
xmlns:pt="http://xmlns.jcp.org/jsf/passthrough">
<h:head>
<title>JSF 2.2</title>
</h:head>
<h:body>
<h:form id="form">
<h:inputText id="email" value="#{bean.email}"
pt:type="email" pt:placeholder="Entre com seu email"/>
</h:form>
</h:body>
</html>
Se olharmos o código fonte renderizado pelo componente h:inputText
, todos os quatro atributos estarão no elemento input
. Portanto, o browser deveria mostrar um campo de tipo email
com um placeholder:
<input id="form:email" name="form:email" value=""
type="email" placeholder="Entre com seu email" />
Quando especificamos um atributo com pass-through attributes, o atributo não é interpretado pelo JSF e é passado diretamente para o HTML gerado. Com isso, podemos ter um controle fino dos atributos gerados pelo componente e aproveitar as novidades do HTML5.
2. Com a tag f:passThroughAttribute
Outra maneira de usar os pass-through attributes, é através da tag f:passThroughAttribute
, como a seguir:
<h:inputText id="email" value="#{bean.email}">
<f:passThroughAttribute name="type" value="email"/>
<f:passThroughAttribute name="placeholder" value="Entre com seu email"/>
</h:inputText>
Dessa forma podemos passar um atributo de cada vez para o componente.
3. Com a tag f:passThroughAttributes
Podemos ir mais longe e passar pass-through attributes de forma dinâmica através de uma propriedade no managed bean com o tipo Map<String, Object>
. Para isso, devemos utilizar a tag f:passThroughAttributes
(repare que está no plural), como no código abaixo:
<h:inputText id="email" value="#{bean.email}">
<f:passThroughAttributes value="#{bean.atributos}" />
</h:inputText>
Neste caso, no managed bean bean
nós teríamos o método getAtributos
dessa forma:
public Map<String, Object> getAtributos() {
Map<String, Object> atributos = new HashMap<>();
atributos.put("type", "email");
atributos.put("placeholder", "Entre com seu email");
return atributos;
}
Com esta tag, não seria difícil carregar atributos customizados de um banco de dados, por exemplo.
4. Programaticamente
Se não estiver satisfeito, é possível adicionar os atributos programaticamente no componente através do método getPassThroughAttributes
:
HtmlInputText inputText = new HtmlInputText();
Map<String, Object> passThrough = inputText.getPassThroughAttributes();
passThrough.put("placeholder", "Entre com seu email");
As diversas formas de trabalhar com pass through attributes nos permitem inserir ou modificar os novos atributos do HTML5 e até mesmo atributos customizados da aplicação que poderão ser trabalhados por código JavaScript no lado cliente, como é o caso dos atributos data-*
.
No curso JSF 2 com Spring utilizamos alguns recursos do HTML5 para melhorar as páginas da aplicação através do pass through attributes do JSF 2.2.
Pass Through Elements
Uma das maiores reclamações com relação ao JSF e a maioria dos frameworks component-based é a ausência de um controle fino do HTML gerado, principalmente com as mudanças trazidas pelo HTML5 e a necessidade de responsividade das páginas. Esse problema normalmente se intensifica quando existe um web designer na equipe, pois para construir as páginas ele teria que trabalhar, entender e arrumar o HTML gerado pelas bibliotecas de componentes. A resposta para resolver isso, sem dúvida, é o recurso Pass Through Elements do JSF 2.2.
Com ele, podemos escrever uma página apenas com HTML puro, porém com a possibilidade de associar os elementos HTML da página a componentes JSF no lado servidor, similar ao que ocorre com o framework Wicket. Para que um elemento HTML da página seja uma pass through element, pelo menos um de seus atributos deve usar a nova namespace http://xmlns.jcp.org/jsf . Fica mais fácil de entender se olharmos o código abaixo:
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:jsf="http://xmlns.jcp.org/jsf">
<head jsf:id="head">
<title>JSF 2.2 - Pass Through Elements</title>
<script jsf:target="body" jsf:name="app.js"/>
<link jsf:name="estilo.css" rel="stylesheet" type="text/css" />
</head>
<body jsf:id="body">
<form jsf:id="form" jsf:prependId="false">
<input jsf:id="email" type="email" jsf:value="#{bean.email}"
placeholder="Entre com seu email" />
<button jsf:action="#{bean.grava}">Envia</button>
</form>
</body>
</html>
Se pelo menos um atributo do elemento HTML estiver usando a nova namespace, o JSF adiciona um componente na árvore de componentes e este é ligado ao elemento da página. O tipo do componente é inferido pelo nome do elemento HTML e por um atributo identificador caso o nome do elemento não seja suficiente.
No código acima, por o elemento head
ter o atributo id
com a namespace jsf
, o JSF adiciona o componente h:head
na árvore, associa-o ao elemento da página e por fim passa o atributo diretamente para o componente. O mesmo acontece para os elementos body
e form
, que são transformados respectivamente em h:body
e h:form
.
No caso do elemento input
, o JSF considera o atributo type
para inferir o componente que será criado na árvore, neste caso um h:inputText
. Atributos não prefixados com a namespace jsf
não são passados para o componente, mas sim diretamente para o HTML gerado, ou seja, segue o mesmo comportamento do pass through attributes.
O mapeamento completo entre os elementos HTML e componentes JSF está definido na documentação da API da classe TagDecorator.
Com a existência de um componente no lado servidor para um pass though element, nós podemos registrar eventos, validadores e conversores suportados pelo componente em questão:
<input type="text" jsf:value="#{bean.nome}">
<f:validateLength maximum="30" />
<f:ajax execute="@this" render="@form" />
</input>
O mais interessante é que se não existe um mapeamento direto para o elemento HTML, um componente especial que suporta AJAX é criado pelo JSF. Dessa forma, podemos adicionar AJAX a qualquer elemento da página sem a necessidade de escrever uma linha de código JavaScript, como no código a seguir:
<div jsf:id="like">
<f:ajax event="click" render="@this" listener="#{bean.like}"/>
</div>
Como pré-requisito para suportar HTML5 nas páginas, o JSF 2.2 por padrão já altera o código das páginas e sempre renderiza o doctype do HTML5 < !DOCTYPE html>
independente do doctype que colocamos no arquivo xhtml.
Tanto o JSF como as bibliotecas de componentes estão caminhando para uma web mais limpa e portável entre navegadores e dispositivos. Com HTML(5) Friendly Markup se tornou possível e fácil para os desenvolvedores e web designers terem um controle mais fino do HTML gerado pelos componentes JSF, além de poderem aproveitar todo o potencial dos novos elementos e atributos do HTML5.
E você, já está utilizando algum recurso do HTML5 nas suas páginas JSF?
You might also be interested in these articles...
Desenvolvedor e instrutor na TriadWorks