Artículos Etiquetados ‘jsf’

Como funciona a4j:jsFunction

19 Octubre 2010

Volviendo a los temas de JSF y Java, hoy día quisiera escribir sobre a4j (Ajax4JSF), una librería que fue integrada al framework Seam y que permite darle una naturaleza AJAX a los componentes JSF tradicionales. En este artículo centraré mi atención en un componente bastante útil denominado jsFunction.

jsFunction es un componente de soporte dentro de la librería y que es usado para poder hacer llamadas asíncronas al servidor desde cualquier código JavaScript que estemos escribiendo. Para tener un punto de referencia podemos decir que se comporta de una manera similar a la etiqueta a4j:commandButton, dado que permite realizar llamadas AJAX al servidor pero de una manera asíncrona.

Veamos un ejemplo:

<script type="text/javascript">
     function validateAndSave() {
       if (validate()) {
          save('all');
       }
     }
</script>
<body>
  <h:form>
    <a4j:jsFunction name="save" action="#{myBean.save()}" reRender="listPanel">
        <a4j:actionParam name="param1" assignTo="#{myBean.aParameter}"/>
    </a4j:jsFunction>
    <a4j:outputPanel id="listPanel">
       ....
    </a4j:outputPanel>
  </h:form>
</body>

Cuando se usa a4j:jsFunction es posible iniciar la petición AJAX desde cualquier JavaScript y hacer una actualización parcial de la página o utilizar la información procesada en el JavaScript que se ejecuta de retorno.

Los siguientes escenarios son ideales para usar el componente:

  • Actualizar registros del lado de la capa Modelo después de cerrar una ventana emergente (popup).
  • Realizar una operación de guardado de información de manera asíncrona.
  • Actualizar una variable que será utilizada luego por otro método (ojo con la llamada asíncrona).

Pueden ver un ejemplo completo en la página de demo de RichFaces. (live demo)

Facelets: el atributo rendered de ui:fragment no es reconocido

17 Septiembre 2010

Como programadores especializados en uno o varios lenguajes o frameworks, en ocasiones utilizamos características que no forman parte de la documentación oficial. En esta oportunidad haré alusión a un elemento en Facelets, el atributo rendered de la etiqueta o tag ui:fragment.

La etiqueta ui:fragment

El tag ui:fragment es utilizado para delimitar un conjunto de componentes en función es similar al elemento ui:component, con la salvedad que no elimina el código que existe alrededor de él.

La documentación oficial indica que esta etiqueta  sólo posee dos atributos (id y binding); sin embargo en varios artículos se indica la existencia de un atributo adicional, rendered, que hace posible que se muestren o no los componentes dependiendo de un valor condicional. En el siguiente ejemplo se muestra un fragmento de código donde aparece este atributo:

<ui:fragment rendered="#{condition}">
   <h:outputText value="text 1"/>
   <h:outputText value="text 2"/>
   <h:outputText value="text 3"/>
</ui:fragment>

¿Cómo es posible que rendered si funcione a pesar de no estar documentado? La razón en realidad es muy simple: los componentes JSF se insertan dentro de un árbol y como tales heredan las propiedades de su componente padre. Por lo tanto, esta excepción funciona porque los componentes hijos heredan el atributo rendered en ui:fragment.

¿Pero si funciona porque busco alternativas?

Los IDEs como NetBeans y Eclipse ya soportan en sus últimas versiones los tags de Facelets y JSF. Estos IDEs resaltan todo texto que no se encuentre conforme a la especificación oficial, y marcaba el código anterior como si se tratase de un error. Es por esta razón que decidí hacer una búsqueda de alternativas para conseguir el mismo resultado.

Entre las alternativas conocidas para esta situación se pueden señalar:

1. Usar otras estructuras agrupadoras:

<s:div rendered="#{condition}">
   <h:outputText value="text 1"/>
   <h:outputText value="text 2"/>
   <h:outputText value="text 3"/>
</s:div>
<s:fragment rendered="#{condition}">
   <h:outputText value="text 1"/>
   <h:outputText value="text 2"/>
   <h:outputText value="text 3"/>
</s:fragment>

Los tags s:div y s:fragment pertenecen a la librería de tags que provee Seam (http://docs.jboss.org/seam/2.2.1.CR2/reference/en-US/html/controls.html) y son estructuras que agrupan componentes, en el caso de s:div se muestra el contenido dentro de un div mientras que s:fragment es una estructura invisible.

Otra estructura que se puede usar es:

<h:panelGroup rendered="#{condition}">
   <h:outputText value="text 1"/>
   <h:outputText value="text 2"/>
   <h:outputText value="text 3"/>
</h:panelGroup>

Si al panel group no se le especifica el valor para id, style o styleClass funciona como entidad agrupada transparente (en caso se le asigne algún valor los componentes se muestran dentro de un span)

2. Usar verbatim si es que el contenido es sólo texto (aunque esto a la larga no es práctico para la mayoría de ocasiones)

<f:verbatim rendered="#{condition}">
   text 1
   text 2
   text 3
</f:verbatim>

3. Poner el atributo rendered a cada uno de los elementos hijos:

<h:outputText value="text 1" rendered="#{condition}"/>
<h:outputText value="text 2" rendered="#{condition}"/>
<h:outputText value="text 3" rendered="#{condition}"/>

Con estas tres opciones es posible generar código válido para la versión de JSF 1.2 y no estar dependiendo de ui:fragment como elemento contenedor.

Combobox JSF con s:convertEnum

7 Octubre 2009

Escribo este post para todos los que alguna vez sufrieron buscando un ejemplo claro y simple de como crear un combobox en base a un Enum en JSF y Seam.

La documentación de Seam (tan clara como el agua) nos nuestra el siguiente ejemplo:

<h:selectOneMenu value="#{person.honorific}">
<s:selectItems value="#{honorifics}" 
                       var="honorific" 
                       label="#{honorific.label}" 
                       noSelectionLabel="Please select" />
   <s:convertEnum />
</h:selectOneMenu>

Donde solo muestran el ejemplo puntual sin dar mayor detalle.
Googleando un poco encontré la siguiente página web donde se dan el trabajo de explicar de una manera sencilla como crear el combobox.

En esa página se muestra el siguiente ejemplo:

XHTML:

<h:selectOneMenu id="marketStatus" 
                 value="#{person.status}"
                 required="true">
    <s:selectItems value="#{enumLists.statusArray}" 
                   var="status"
                   label="#{status}"
                   noSelectionLabel="Select a status..."/>
    <s:convertEnum/>
</h:selectOneMenu>

ENUM:

@Name("enumLists")
@Scope(ScopeType.STATELESS)
public class EnumLists {
   public Status[] getStatusArray() {
     return Status.values();
   }
}

Como se puede ver en el ejemplo han expuesto el Enum como un Seam bean stateless y retornando la lista de valores con status.values().
Para poner un label a cada opción utilizan el toString() del Enum dado que en label colocan label=”#{status}”

Como pueden ver hacer un combobox basado en un Enum es bastante sencillo y útil.

Frameworks para iPhone

4 Agosto 2009

Hace algunas semanas en Antartec se nos encargó desarrollar una aplicación web piloto, ésto no tendría mucha novedad y/o relevancia como para escribir un post sobre ello, sin embargo el objetivo planteado lo hizo particularmente interesante.

El reto en esta aplicación fue desarrollar una web que se comporte como una aplicación nativa de iPhone y que le permita a los usuarios ingresar información en tiempo real al sistema sin encontrarse frente a un computador.

Nuestros esfuerzos se concentraron en expandir nuestro actual framework basado en JSF y SEAM para que soporte el formato iPhone; nuestras investigaciones preliminares dieron frutos y encontramos varios frameworks para simular la apariencia de interfaces nativas en iPhone tales como iUI y UiUI (Universal).
» Leer más: Frameworks para iPhone

Carga dinámica de combos usando JSF y richfaces

28 Enero 2009

La carga dinámica de un combo basado en la selección de un combo previo es un problema relativamente clásico y que ha sido abordado de distintas maneras a lo largo del tiempo.

En este post queremos mostrarles como es que nosotros abordamos el tema usando componentes JSF y de Richfaces para resolver el problema.

» Leer más: Carga dinámica de combos usando JSF y richfaces