Olá Pessoal,
Depois de passar uns 2 ou 3 dias varendo os forums na internet em busca da solução para um problema (JÁ RESOLVIDO FINALMENTE), definitivamente me veio está pergunta: JSF está maduro ou apenas começando?.
Vejam abaixo o “RESUMO” do meu problema para chegar a esta questão:
Título:
Problema de Incompatibilidades entre Browsers e componentes JSF
Tarefa:
Criar um link que ao ser clicado, abre a tela de download de um relatório. No link deseja-se passar como parâmetro o formato do relatório desejado (PDF ou RTF).
Tentativa Inicial de Solução:
Como o padrão do projeto é ajax e estamos usado RichFaces, o normal seria usar as tags do RichFaces, conforme abaixo:
<a4j:form>
<a4j:commandLink action="#{relResgatesBean.download}">
<h:graphicImage value="/sistemaweb/images/pdf.gif" width="32" height="32" />
<a4j:actionparam name="relatorioTipo" value="PDF" assignTo="#{relResgatesBean.relatorioTipo}"/>
</a4j:commandLink>
<a4j:commandLink action="#{relResgatesBean.download}">
<h:graphicImage value="/sistemaweb/images/rtf.gif" width="32" height="32" />
<a4j:actionparam name="relatorioTipo" value="RTF" assignTo="#{relResgatesBean.relatorioTipo}"/>
</a4j:commandLink>
<a4j:form>
Problema A:
O código da action #{relResgatesBean.download} que abre a tela de download não funciona com o a4j:commandLink do RichFaces.
Solução A:
Usar o <h:commandLink>. Agora o código ficou assim:
<a4j:form>
<h:commandLink action="#{relResgatesBean.download}">
<h:graphicImage value="/sistemaweb/images/pdf.gif" width="32" height="32" />
<a4j:actionparam name="relatorioTipo" value="PDF" assignTo="#{relResgatesBean.relatorioTipo}"/>
</h:commandLink>
<h:commandLink action="#{relResgatesBean.download}">
<h:graphicImage value="/sistemaweb/images/rtf.gif" width="32" height="32" />
<a4j:actionparam name="relatorioTipo" value="RTF" assignTo="#{relResgatesBean.relatorioTipo}"/>
</h:commandLink>
<a4j:form>
Problema B:
Se o arquivo .xhtml que contém esse código JSF da “Solução A” for carregado normalmente no Internet Explorer ou no Firefox ele funciona normalmente.
Como o projeto usa AJAX, esse código vem via AJAX, e ai ocorre o Problema B. Quando se carrega via AJAX esses <h:commandLink> não funcionam no Firefox.
Solução B:
Se trocarmos os camponentes <h:commandLink> para <h:commandButton> funciona. Agora o código ficou assim:
<a4j:form>
<h:commandButton action="#{relResgatesBean.download}">
<h:graphicImage value="/sistemaweb/images/pdf.gif" width="32" height="32" />
<a4j:actionparam name="relatorioTipo" value="PDF" assignTo="#{relResgatesBean.relatorioTipo}"/>
</h:commandButton>
<h:commandButton action="#{relResgatesBean.download}">
<h:graphicImage value="/sistemaweb/images/rtf.gif" width="32" height="32" />
<a4j:actionparam name="relatorioTipo" value="RTF" assignTo="#{relResgatesBean.relatorioTipo}"/>
</h:commandButton>
<a4j:form>
Problema C:
Como agora temos um botão ao invés de um link, caimos num problema de design. Não podemos mais usar o <h:graphicImage>.
Mas como quero um ícone ao invés de um botão, tenho que camuflar o botão. Ou seja, altero o CSS do botão para ele ele pareça um Link de Ícone.
Então criei o seguinte CSS:
input[type="submit"].buttonPdf,
input[type="submit"].buttonRtf {
background: url('../images/icones/pdf.gif');
width:32px;
height:32px;
border: 0px;
padding: 0px;
cursor: pointer;
}
input[type="submit"].buttonRtf {
background: url('../images/icones/rtf.gif');
}
Agora o código ficou assim:
<a4j:form>
<h:commandButton action="#{relResgatesBean.download}" value="" styleClass="buttonPdf">
<a4j:actionparam name="relatorioTipo" value="PDF" assignTo="#{relResgatesBean.relatorioTipo}"/>
</h:commandButton>
<h:commandButton action="#{relResgatesBean.download}" value="" styleClass="buttonRtf">
<a4j:actionparam name="relatorioTipo" value="RTF" assignTo="#{relResgatesBean.relatorioTipo}"/>
</h:commandButton>
<a4j:form>
Problema D:
Voltando ao JSF, como agora temos um botão, os parâmetros não funcionam a4j:actionparam. Neste caso foram encontradas duas possíveis soluções:
Solução D1:
Usar um “actionListener” ao invés de “action” e um <f:param> ao invés do a4j:actionparam. O código ficaria assim:
<a4j:form>
<h:commandButton actionListener="#{relResgatesBean.download}" value="" styleClass="buttonPdf">
<f:param name="relatorioTipo" value="PDF" />
</h:commandButton>
<h:commandButton actionListener="#{relResgatesBean.download}" value="" styleClass="buttonRtf">
<f:param name="relatorioTipo" value="RTF" />
</h:commandButton>
<a4j:form>
Teríamos que alterar o Bean conforme abaixo:
public void download(ActionEvent event) {
UIParameter parameter = (UIParameter) event.getComponent().findComponent("relatorioTipo");
String relatorioTipo = parameter.getValue().toString();
...
}
Obs: Não cheguei a testar mas talvez se usar a4j:actionparam ao invés de <f:param> também pode funcionar com a Solução D1.
Solução D2:
Usar o componente do Tomahawk <t:updateActionListener> ou invés de: <f:param> ou a4j:actionparam
O código ficaria assim:
<a4j:form>
<h:commandButton action="#{relResgatesBean.download}" value="" styleClass="buttonPdf">
<t:updateActionListener property="#{relResgatesBean.relatorioTipo}" value="PDF" />
</h:commandButton>
<h:commandButton action="#{relResgatesBean.download}" value="" styleClass="buttonRtf">
<t:updateActionListener property="#{relResgatesBean.relatorioTipo}" value="RTF" />
</h:commandButton>
<a4j:form>
Comentário 1:
Como já tinha o Tomahawk no projeto, acabei optando pela Solução D2.
Comentário 2:
Na época para usar o Tomahawk com Facelets tive que pesquisar como fazer isso e também deu um certo trabalho e algumas configurações extras.
Comentário 3:
Essa salada de RichFaces, Tomahawk, Facelets, Scripts personalizados e CSS para personalizar superficialmente alguns componentes do RichFaces gera problemas como:
[list]As vezes os componentes não obedecem o CSS personalizado. Ai só um Refresh para resolver o problema.[/list][list]Como são muitos arquivos JavaScript, localmente tudo roda bem, mas na internet, onde o tempo de resposta é maior, temos vários erros provocados por javascripts não carregados.[/list]
Comentário 4:
Pode até ser que eu seja o inexperiente com JSF para ter passado por isso, mas acredito que essas coisas devam ser mais fáceis.
Bom pessoal, eu reportei o problema que passei apenas para ser a inspiração e justificativa para se fazer a pergunta: JSF está maduro ou apenas começando?
Agora gostaria de conheçer o que vocês acham a respeito!!!
Abrs. :lol:
Claudiney