Posts Tagged ‘JSF’

O que um TimeZone pode fazer por você

As vezes, o uso de algumas combinações pregam uma grande peça.

Neste post, vou expor algo que acontece quando se usa ICEFaces para manipular datas através do componente selectInputDate combinado com o conversor convertDateTime.

O uso do trecho de código abaixo…

<ice:selectInputDate id="dataInicio"
    renderMonthAsDropdown="true" renderYearAsDropdown="true"
    title="Selecione a Data" renderAsPopup="true"
    required="true" value="#{meuBackingBean.dataInicio}"
    partialSubmit="true">
    <f:convertDateTime pattern="dd/MM/yyyy HH:mm:ss"/>
</ice:selectInputDate>

… produz um resultado BEM DIFERENTE do trecho de código abaixo.

<ice:selectInputDate id="dataInicio"
    renderMonthAsDropdown="true" renderYearAsDropdown="true"
    title="Selecione a Data" renderAsPopup="true"
    required="true" value="#{meuBackingBean.dataInicio}"
    partialSubmit="true">
    <f:convertDateTime pattern="dd/MM/yyyy"/>
</ice:selectInputDate>

E quando digo diferente, digo da pior maneira possível.

Antes de mostrar o resultado, perceberam a diferença entre as implementações?

A única diferença está na definição do pattern na tag convertDateTime.

Suponhamos que neste objeto seja selecionado a data de 03/02/2010, e isto foi feito as 17h52.

Para o trecho com o pattern indicando dd/MM/aaaa HH:mm:ss, o resultado da definição do atributo dataInicio no Backing Bean é “setDataInicio=Wed Feb 03 17:52:28 BRST 2010″. Correto, se o componente não tivesse exibido estas mesmas informações no input com o horário 2h a frente.

Para o trecho com o pattern indicando dd/MM/aaaa, o resultado da definição do atributo dataInicio no Backing Bean é “setDataInicio=Wed Feb 02 22:00:00 BRST 2010″. Errado, bem errado. Notem que aqui o componente, por algum motivo, criou ou formatou a data/hora usando o timezone GMT e subtraiu 2h (já que estamos no timezone America/Sao_Paulo).

O que fazer para solucionar isso?

Para resolver esta questão será necessário adicionar o atributo timeZone no formatador convertDateTime.

<ice:selectInputDate id="dataInicio"
    renderMonthAsDropdown="true" renderYearAsDropdown="true"
    title="Selecione a Data" renderAsPopup="true"
    required="true" value="#{meuBackingBean.dataInicio}"
    partialSubmit="true">
    <f:convertDateTime pattern="dd/MM/yyyy" timeZone="#{meuBackingBean.timeZone}"/>
</ice:selectInputDate>

Neste caso, adicionamos #{meuBackingBean.timeZone} como valor do atributo timeZone.Por algum motivo, esta definição torna-se obrigatória para que a data não seja criada com horário incorreto.

No Backing Bean, o que devemos implementar é:

@Component
@scope("session")
public class MeuBackingBean.... {

private java.util.Timezone timeZone = TimeZone.getDefault();
...

public TimeZone getTimeZone() {
    return this.timeZone;
}

}

Adicionando Ajuda (Tooltip) em seu formulário

Aplicações Web apresentam em algum momento algum tipo de formulário que precisa ser preenchido pelos usuários. Aplicações de uma intranet são cheios desse recurso. E com isso, o uso de qualquer tipo de ajuda em preenchimento pode ser necessário.

Com isso, programadores podem usar recursos do tipo Tooltip (aquele quadro flutuante que aparece em algum momento quando o mouse está acima de algum objeto). A implementação HTML possui o atributo title que faz com que o navegador apresente um recurso de tooltip simples.

Neste tutorial, vou mostrar como fazer algo um pouco mais interessante / livre com o uso do framework ICEFaces. Mas não vou apenas demonstrar o uso nu e cru do compomente que este framework dispõe.

Os formulários que uma aplicação implementa, normalmente, segue padrões de design da instituição. E com essa visão, podemos construir componentes Facelets customizados.

Para criar um componente customizado, precisaremos fazer 3 coisas;

1) Criar o componente Tooltip

2) Criar a taglib

3) Declarar a taglib no web.xml

4) Importar a taglib usando namespace

Criar o Componente Tooltip

Para criar um componente customizado, crie um arquivo com o nome “input-component.jspx” (neste caso, os arquivos jspx serão mapeados para renderizar o framework ICEFaces).

Este primeiro trecho define os namespaces das bibliotecas que podem ser utilizadas no componente.

<html  xmlns:jsp="http://java.sun.com/JSP/Page"
	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:c="http://java.sun.com/jstl/core"
	xmlns:ice="http://www.icesoft.com/icefaces/component">

Este trecho define que o componente será uma composição, que não apresenta conteúdos fora da tag .

<ui:composition>

Este trecho define o comportamento do nosso componente.

<tr>
   <td class="label"><ice:outputLabel for="#{label}">#{labelValue}</ice:outputLabel> <c:if test="${required == true}">(*)</c:if> : </td>
   <td>
     <ice:inputText id="#{field}" value="#{fieldValue}" required="#{required}" maxlength="#{maxlength}" size="#{size}" styleClass="cssInputStyle" readonly="#{readonly}" tabindex="#{tabindex}">
     <f:validateLength minimum="#{minimum}"/>
     <f:converter converterId="CustomInputTextConverter"/>
     </ice:inputText>
     <ice:panelGroup panelTooltip="#{label}Tooltip"><ice:graphicImage id="#{label}Image" url="/images/ajuda.gif"/></ice:panelGroup>
     <ice:panelTooltip id="#{label}Tooltip" displayOn="hover" hideOn="mouseout" hoverDelay="300" styleClass="cssTooltipStyle">
         <f:facet name="body"><ice:outputText value="#{ajuda}"/></f:facet>
     </ice:panelTooltip>
     <h:message for="#{label}" errorClass="cssErrorStyle"/>
   </td>
 </tr>

Este componente define uma entrada TR com 2 colunas (aqui estamos supondo que a definição da TABLE será feita no arquivo JSPX que usará o componente).

A primeira coluna conterá a definição do LABEL e a segunda coluna conterá a definição do objeto de INPUT e de uma imagem para o Tooltip.

Como pode ver, este componente constrói a representação de apenas 1 interação do usuário no formulário com 1 LABEL, 1 INPUT e 1 Tooltip. Isso tudo com mais de 10 linhas de instruções HTML e componentes ICEFaces.

Neste último trecho finalizamos o componente.

</ui:composition>
</html>

Criar a Taglib

Depois de criar o arquivo do nosso componente, precisamos criar o arquivo que será a definição da taglib. Crie o arquivo “tutorial.taglib.xml” e adicione o código abaixo.

          <facelet-taglib>
              <namespace>http://www.faque.com.br/jsf</namespace>
              <tag>
                <tag-name>inputField</tag-name>
                <source>../inc-components/input-component.jspx.jspx</source>
              </tag>
          </facelet-taglib>

O namespace será utilizado para você utilizar em suas outras implementações JSP. A tag define como o componente será identificado.

Declarar a Taglib no web.xml

Uma vez que a taglib está criada, esta precisa estar definida no arquivo web.xml

          <context-param>
              <param-name>facelets.LIBRARIES</param-name>
              <param-value>/WEB-INF/facelets/tags/tutorial.taglib.xml<param-value>
          </context-param>

Exemplo da chamada

Primeiramente, você precisa definir o namespace em algum trecho do seu arquivo JSP para que possa utilizar da taglib. Há algumas maneiras possíveis. A apresentada abaixo, define o namespace em uma DIV.

<div  xmlns:fw="http://www.faque.com.br/jsf>
<fw:inputField label="nome" labelValue="#{lbl['label.nome']}"
		field="nome" fieldValue="#{tutorialBBean.entity.nome}"
		required="true" maxlength="50" size="50" tabindex="1" readonlyOnUpdate="false"
		ajuda="Nome para o Tutorial que será aplicado aos funcionários"/>

Muito simples não?

Espero que este tutorial seja útil.

ICEFaces lança versão comercial

A ICEsoft acabou de anunciar uma versão comercial de seu framework JSF em AJAX chamado ICEFaces. Trata-se do ICEFaces EE.

Este empacotamento adiciona os seguintes itens em relação à versão OpenSource:

  • Technical Resources
    • Enterprise Deployment Guides and Documentation
  • Software
    • Composite Component Library
    • Facelet Application Templates
    • Functional and Load Testing Scripts
    • Enterprise Push Server
  • Support (with SLA)

O ICEFaces EE possui 5 opções de subscrição com valor inicial de US$ 499 doletas.

Estou AQUI

Tags
Desafie meu Brute