Quando se fala em usabilidade de sistemas, as modal panels, ou também conhecidas como pop-ups, ou simplesmente modais, se tornam essenciais para facilitar pequenas e rápidas ações do usuário ou para o carregamento de novas informações à partir de alguma ação do sistema. No entanto, quando se fala de criar tais recursos utilizando JSF, de maneira a obter boa performance e fácil utilização, para a grande maioria programadores a tarefa se torna um tanto quanto complexa.
Este post visa, portanto, mostrar como fazer estas modais de
uma maneira simples e prática.
Os principais desafios enfrentados pelos programadores são:
- o carregamento das modais é lento;
- a abertura da modal só ocorre após a requisição feita ao servidor;
- após a requisição, para a abertura da modal, é necessário antes que toda a árvore de objetos do JSF seja atualizada;
- pouco feedback (mensagens de retorno) ao usuário sobre o carregamento ou gravação dos dados.
A solução:
Visando sanar a todos estes problemas, eis aqui uma solução
passo-a-passo a que cheguei à conclusão, após pesquisar alguns métodos. Darei
um exemplo de alteração de uma determinada data, mediante digitação da
justificativa pelo usuário:
Passo 1: incluir a chamada no evento que abrirá a modal da seguinte forma:
<a4j:commandLink value="#{msgs.comando_geral_alterar}"
actionListener="#{meuManagedBean.exibirAlteracao}"
onclick="Richfaces.showModalPanel('painelAlteracaoDados');"
reRender="painelDadosAlteracao"
ajaxSingle="true">
</a4j:commandLink>
Neste caso estou chamando o Managed Bean, como "meuManagedBean", no qual terá a ação ajax a ser
executada, confome colocado no atributo "actionListener
". A modal abrirá instantaneamente
com o evento onclick, que chamará um javascript para abrir a modal que chamei
de "painelAlteracaoDados". O atributo reRender,
renderizará o painel que está dentro da modal "painelDadosAlteracao
" com o resultado da busca ajax. Conforme código do próximo passo abaixo.
Passo 2: criar a modal como um componente:
<?xml version="1.0" encoding="UTF-8"
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:a4j="http://richfaces.org/a4j"
xmlns:rich="http://richfaces.org/rich">
<ui:composition>
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:a4j="http://richfaces.org/a4j"
xmlns:rich="http://richfaces.org/rich">
<ui:composition>
<rich:modalPanel id="painelAlteracaoDados" autosized="true"
zindex="2000">
<f:facet name="header">
<h:panelGroup>
<h:outputText value="#{msgs.nome_tela_altera_dados}" />
</h:panelGroup>
</f:facet>
<f:facet name="controls">
<h:panelGroup>
<a4j:ajaxCommandButton id="hideImageAlteracaoDados" immediate="true"
ajaxSingle="true" image="/imagens/close.png"
action="#{CotacaoBean.alterarDisplayModalAlteracaoDados}"
/>
<rich:componentControl for="painelAlteracaoDados"
attachTo="hideImageAlteracaoDados" operation="hide" event="onclick"
/>
</h:panelGroup>
</f:facet>
<rich:panel id="painelDadosAlteracaoDados" rendered="${rendered}">
<h:form id="formularioAlteracaoDados">
<a4j:region id="processamentoModalDados">
<h:panelGrid columns="2" width="100%">
<a4j:calendar id="dataAlteracao"
value="#{meuManagedBean.data}"
datePattern="dd/MM/yyyy HH:mm" enableManualInput="true" />
<a4j:inputTextarea id="justificativaAlteracaoDados"
value="#{meuManagedBean.justificativa}" />
</h:panelGrid>
<rich:messages style="color:darkred"
id="mensagemErroAlteracaoDados" />
<h:inputHidden id="idAlteracao" value="#{meuManagedBean.id}" />
<a4j:ajaxCommandButton id="saveButtonAlteracaoDados"
reRender="painelDadosAlteracaoDados, mensagemModal"
value="#{msgs.comando_geral_salvar}"
action="#{meuManagedBean.alterarDados}" ajaxSingle="true"
process="dataAlteracao, justificativaAlteracaoDados,
idAlteracao" />
<a4j:ajaxCommandButton id="hideButtonAlteracaoDadosCancelar"
value="#{msgs.comando_geral_fechar}"
action="#{meuManagedBean.alterarDisplayModalAlteracaoDados}"
ajaxSingle="true"
immediate="true" />
<rich:componentControl for="painelAlteracaoDados"
attachTo="hideButtonAlteracaoDadosCancelar" operation="hide"
event="onclick" />
<a4j:status>
<f:facet name="start">
Salvando...
</f:facet>
</a4j:status>
</a4j:region>
</h:form>
</rich:panel>
</rich:modalPanel>
</ui:composition>
</html>
Repare que estou criando a modal como um
"ui:composition" para que a mesma seja um componente do Facelets. A renderização da data a ser alterada, se dará na região
demarcada pela tag "a4j:region". Isto indica ao JSF que não é necessário
carregar toda a árvore de componentes uma vez que a modal já está aberta, mas
somente deve recarregar o que nos interessa: os campos que foram populados pela
requisição ajax.
Foi utilizado também a tag "a4j:status"
para que, enquanto o salvamento das informações é processado, exiba a mensagem
"salvando..." ao usuário.
Repare que o controle do carregamento das informações e
fechamento da modal se dá pelo atributo "rendered"
colocado no painel que circunda todo o conteúdo da modal. O que indicará então
se a modal recarregará os dados (rendered="true") ou se fechará após
tudo ser salvo com sucesso (rendered="false") é uma variável booleana
que o método ajax do Managed Bean alterará. O código do método do Managed Bean
está no passo 4.
O outro componente citado pelo reRender, "mensagemModal", nada mais é que outra modal
criada apenas para exibir mensagens de sucesso ao usuário após esta modal
principal se fechar. Você pode substituí-la por uma região da página principal
(a chamadora) que exibirá sua mensagem.
Passo 3: incluir o
seguinte código que monta o componente modal, na mesma tela do evento chamador:
<componente:alteraDadosModal rendered="${meuManagedBean.displayModalAlteracaoDados}" />
O "displayModalAlteracaoDados
" é a variável booleana de controle da exibição, de que comentei
anteriormente. Ela é controlada pelos métodos seguintes.
Passo 4: os métodos de abertura e processamento do Managed Bean:
public void exibirAlteracaoDados(ActionEvent event) {
setData(dataService.buscarData());
this.setDisplayModalAlteracaoVencimento(true);
}
public void alterarDados(ActionEvent
event) {
dataService.salvarAlteracao(id, data, justificativa);
this.setMensagem(TIPO_MENSAGEM_MODAL, ALTERACAO_VENCIMENTO_SUCESSO);
this.setDisplayModalAlteracaoVencimento(false);
this.setDisplayModalAlteracaoVencimento(false);
}
Bom, é isto. Espero que este
exemplo e explicações sejam úteis aos programadores que estiverem necessitando
utilizar este bom recurso do JSF.
Fiquem à vontade para comentar ou
postar dúvidas! =)
aeeeeeeeeeeee parabéns pelo post, muito bomm
ResponderExcluirAss: sua fã
Te amo!