Exemplo Composite + JSF2
Wednesday, 3. August 2011
Para criar um componente usando Composite no JSF2 é bem simples. Abaixo vou mostrar um componente que criei para um caso em específico, basta abstrair e usar para o que precisar.
No meu caso, o meu projeto fazia uso do primefaces, então caso você use alguma outra biblioteca, basta substituir pelos componentes correspondentes aos que eu usei do primefaces.
Mãos a obra:
Pra começar, existe um padrão em que deve ser criado uma pasta chamada “resources” dentro da “webapp”, e dentro dela a pasta que será a base de sua lib de componentes, no nosso caso: “telefone”.
Dentro da pasta “telefone” crie uma xhtml que será o seu componente em sí, telefone.xhtml:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:cc="http://java.sun.com/jsf/composite"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:p="http://primefaces.prime.com.tr/ui">
<cc:interface>
<cc:attribute name="telefoneExclusao" required="true" />
<cc:attribute name="propertyListaTelefone" required="true" />
<cc:attribute name="actionNovoTelefone"
method-signature="void action()" />
<cc:attribute name="actionExcluirTelefone"
method-signature="void action()" />
</cc:interface>
<cc:implementation>
<p:panel header="#{msg['label_componente_telefone_listaTelefones']}">
<f:facet name="options">
<p:menu>
<p:menuitem value="#{msg['label_novo']}"
action="#{cc.attrs.actionNovoTelefone}" ajax="false" />
</p:menu>
</f:facet>
<p:dataTable value="#{cc.attrs.propertyListaTelefone}" var="item"
id="listaTelefone" update="@form" >
<p:column>
<f:facet name="header">
</f:facet>
<p:inputMask mask="9999-9999" value="#{item.numero}" />
</p:column>
<p:column>
<f:facet name="header">
<h:outputText value="#{msg['label_ramal']}" />
</f:facet>
<p:inputMask mask="9999" value="#{item.ramal}" />
</p:column>
<p:column>
<f:facet name="header">
<h:outputText value="#{msg['label_observacao']}" />
</f:facet>
<p:inputText value="#{item.observacao}" />
</p:column>
<p:column>
<f:facet name="header">
<h:outputText value="#{msg['label_excluir']}" />
</f:facet>
<p:commandButton value="#{msg['label_excluir']}"
action="#{cc.attrs.actionExcluirTelefone}">
<f:setPropertyActionListener
target="#{cc.attrs.telefoneExclusao}" value="#{item}" />
</p:commandButton>
</p:column>
</p:dataTable>
</p:panel>
</cc:implementation>
</html>
Algumas considerações devem ser feitas sobre meu componente acima, por exemplo:
value=#{msg['label_novo']}
Essa variável msg é um Helper que eu criei para buscar valores do meu Bundle, no caso de quem estiver fazendo isso do zero, basta usar value=”Novo” que vai funcionar perfeitamente.
Quanto a minha interface:
<cc:interface> <cc:attribute name="idTelefoneExclusao" required="true" /> <cc:attribute name="propertyListaTelefone" required="true" /> <cc:attribute name="actionNovoTelefone" method-signature="void action()" /> <cc:attribute name="actionExcluirTelefone" method-signature="void action()" /> </cc:interface>
Você irá precisar passar para o componente <telefone:telefone> os seguintes atributos:
telefoneExclusaoactionNovoTelefoneactionExcluirTelefone
<f:setPropertyActionListener target="#{cc.attrs.telefoneExclusao}" value="#{item}" />
No meu TesteMBean.java criei as entidades e métodos a seguir:
private List<TelefoneEntity> listaTelefone;
private TelefoneEntity telefoneExclusao;
@PostConstruct
public void initialize() {
if(conversation.isTransient())
conversation.begin();
listaTelefone = new ArrayList();
TelefoneEntity o = new TelefoneEntity();
o.setId(1L);
o.setNumero("1231-2223");
o.setObservacao("obs");
listaTelefone.add(o);
}
public void excluirTelefone(){
telefoneExclusao.getId(); // crie aqui seu metodo de excluir o telefone
}
public void novoTelefone(){
if(listaTelefone == null){
listaTelefone = new ArrayList();
}
TelefoneEntity o = new TelefoneEntity();
o.setId(2L);
o.setObservacao("novo");
listaTelefone.add(o);
}
Meu TesteMBean é apenas um exemplo, pois cada um deve implementar conforme as suas necessidades.
Por fim, para usar o componente basta apenas chamá-lo passando os parametros correspondentes aos que criamos.
<telefone:telefone
propertyListaTelefone="#{testeMBean.listaTelefone}"
actionExcluirTelefone="#{testeMBean.excluirTelefone}"
actionNovoTelefone="#{testeMBean.novoTelefone}"
telefoneExclusao="#{testeMBean.telefoneExclusao}" />
Não esquecendo de importar o componente lá no cabeçalho do xhtml:
<ui:composition xmlns="http://www.w3.org/1999/xhtml" xmlns:ui="http://java.sun.com/jsf/facelets" xmlns:f="http://java.sun.com/jsf/core" xmlns:h="http://java.sun.com/jsf/html" xmlns:p="http://primefaces.prime.com.tr/ui" xmlns:telefone="http://java.sun.com/jsf/composite/telefone">
Ele ficará assim: