Como funciona a4j:jsFunction

19 Octubre 2010 por Juan Eladio Sánchez Rosas Sin comentarios »

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 por Juan Eladio Sánchez Rosas Sin comentarios »

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.

JQuery API browser

5 Mayo 2010 por Juan Eladio Sánchez Rosas Sin comentarios »

Uno de los aspectos más importantes para dominar y hacer uso de una tecnología es tener acceso a buena documentación. En el caso específico de la librería JQuery se cuenta con gran cantidad de información disponible en su sitio web, además de recursos de programadores con ejemplos prácticos de uso.

Sin embargo, la documentación oficial de la herramienta es presentada en páginas independientes, por lo que navegar a través de ellas buscando información específica resulta complicado. Es por ello que quiero compartirles una utilidad que permite encontrar rápidamente mayores detalles de cualquier función de JQuery.

Pantallazo-jQuery API Browser v1.3

La herramienta, JQuery API browser es accesible de dos maneras: la primera es mediante la aplicación web que utiliza una interfaz AJAX para saltar entre funciones de la librería y la segunda mediante una aplicación de escritorio basada en Adobe Air.

Espero la disfruten tanto como yo lo he hecho.

Usando JQuery Dialog con IFrame

3 Mayo 2010 por Juan Eladio Sánchez Rosas 17 comentarios »

JQuery es una excelente librería JavaScript que simplifica la manipulación del DOM (Document Object Model) de una página HTML, el manejo de eventos, animaciones y AJAX. Así también, desde hace un tiempo atrás provee una librería de componentes UI que extiende los componentes iniciales de esta librería.

El widget de tipo diálogo es un ventana flotante que tiene un título y contenido (similar a un popup). Este widget resulta ser muy útil para mostrar alertas o formularios que el usuario debe llenar antes de poder continuar. Veamos como lograr lanzar un dialog apenas carga la página

<script type="text/javascript" src="/assets/javascript/jquery-1.4.min.js"></script>
<script type="text/javascript" src="/assets/javascript/jquery-ui-1.8.custom.min.js"></script>
 
<script type="text/javascript">
 
$(function() {
 $("#dialog").dialog();
});
 
</script>
 
<div id="dialog" title="Basic dialog">
        <p>This is the default dialog which is useful for displaying information. The dialog window can be moved, resized and closed with the 'x' icon.</p>
</div>

Ejemplo tomado de la página web de Jquery

Como puede apreciarse en el código anterior, esta es una solución muy sencilla para hacer un widget dialog; sin embargo, cuando se desarrolla un sistema de mayor complejidad lo ideal es separar las ventanas en múltiples archivos y los diálogos no son la excepción. Una implementación bastante difundida en la web es utilizar un elemento iframe en vez de una etiqueta div para construir el contenido del diálogo. Veamos un ejemplo para que quede más clara la idea.

<script type="text/javascript">
 
$(function() {
        $('a.showPopup').click(function(e) {
            e.preventDefault();
            var $this = $(this);
            var horizontalPadding = 15;
            var verticalPadding = 15;
            $('<iframe id="site" src="' + this.href + '" />').dialog({
                title: ($this.attr('title')) ? $this.attr('title') : 'Site',
                autoOpen: true,
                width: 600,
                height: 300,
                modal: true,
                resizable: false,
                autoResize: true,
                overlay: {
                    opacity: 0.5,
                    background: "black"
                }
            }).width(600 - horizontalPadding).height(300 - verticalPadding);
        });
});
 
</script>
 
<a class="showPopup" href="http://www.google.com" title="Google">

Como puede apreciarse en el ejemplo anterior, se utiliza un pseudo iframe, al cual le asignamos la dirección con el contenido que queremos mostrar en el diálogo. Algunas posibles mejoras a esta idea inicial sería crear una función que permita reutilizar el código en otros enlaces, pero eso se los dejo como tarea.

EDIT:
Respondiendo aun pregunta realizada por un lector estoy agregando una manera de cerrar el diálogo desde el iframe mismo:

<script type="text/javascript">
var refDialog;
$(function() {
...
refDialog = $('<iframe id="site" src="' + this.href + '" />').dialog(...);
...
});
</script>

Dentro del iFrame colocar un link de la siguiente manera:

<a href="javascript:void(0);" onclick="window.parent.refDialog.dialog('close');">close</a>

Primeras Impresiones de Django

29 Marzo 2010 por Juan Eladio Sánchez Rosas 1 comentario »

Hace poco empezamos a probar Django, uno de los frameworks web más populares para el lenguaje Python. Nos gustaría compartir las características que nos han parecido impresionantes y algunas que no nos han gustado.

Lo más impresionante: el sitio de administración

El “admin site”, como le llaman los Djangonautas, es más que un simple scaffolding para el back-end, puesto que construye una interfaz más avanzada.

Django puede deducir información de los modelos para generar automáticamente las páginas de administración de los objetos de negocio, desde donde se realizan todas las operaciones sobre base de datos: lectura, actualización, creación, eliminación, validación, relación con otros objetos, etc. Así, los usuarios administradores puedan agregar contenido al sitio y tenerla lista para mostrar a los clientes finales.

» Leer más: Primeras Impresiones de Django