JBoss RichFaces. Capítulo 3. Primeros pasos.

19
3 Primeros pasos En este capítulo, empezaremos a entender cómo escribir una aplicación rica utilizando RichFaces. Con el fin de hacer esto, hemos decidido empezar con un ejemplo sencillo que implementa una lista de contactos al estilo Ajax. El usuario será capaz de listar, agregar y eliminar contactos, sin necesidad de recargar la página del navegador. Vamos a ver cómo algunos componentes importantes de Ajax trabajan y cómo ajaxizaremos una aplicación JSF utilizando los conceptos del marco de trabajo RichFaces. Las características desarrolladas en este ejemplo se verán en profundidad en los próximos capítulos. Un administrador de contactos La aplicación de ejemplo es un simple administrador de contactos, tiene una lista de contactos y un formulario para añadir nuevos contactos. También, puede eliminar un contacto específico de la lista. El ejemplo muestra cómo funciona el marco de Ajax y cómo se puede utilizar los componentes Ajax RichFaces. También utiliza algunos componentes gráficos RichFaces como: rich:panel, rich:spacer, y rich:separator. Se utiliza el componente rich:calendar para la entrada de la fecha, y la versión RichFaces de dataTable (rich:dataTable y rich:column) con capacidad de filtrado automático y de ordenación. También usamos el componente de validación de Ajax (rich:beanValidator) para ajaxizar y mejorar la validación de JSF estándar. El tema (skin) que hemos elegido puede cambiar editando el nombre del tema en el archivo web.xml (veremos cómo hacer ésto en los capítulos siguientes).

description

En este capítulo, empezaremos a entender cómo escribir una aplicación rica utilizando RichFaces.Con el fin de hacer esto, hemos decidido empezar con un ejemplo sencillo que implementa una lista de contactos al estilo Ajax. El usuario será capaz de listar, agregar y eliminar contactos, sin necesidad de recargar la página del navegador.Vamos a ver cómo algunos componentes importantes de Ajax trabajan y cómo ajaxizaremos una aplicación JSF utilizando los conceptos del marco de trabajo RichFaces.Las características desarrolladas en este ejemplo se verán en profundidad en los próximos capítulos.

Transcript of JBoss RichFaces. Capítulo 3. Primeros pasos.

Page 1: JBoss RichFaces. Capítulo 3. Primeros pasos.

3 Primeros pasos

En este capítulo, empezaremos a entender cómo escribir una aplicación rica utilizando RichFaces. Con el fin de hacer esto, hemos decidido empezar con un ejemplo sencillo que implementa una lista de contactos al estilo Ajax. El usuario será capaz de listar, agregar y eliminar contactos, sin necesidad de recargar la página del navegador. Vamos a ver cómo algunos componentes importantes de Ajax trabajan y cómo ajaxizaremos una aplicación JSF utilizando los conceptos del marco de trabajo RichFaces. Las características desarrolladas en este ejemplo se verán en profundidad en los próximos capítulos.

Un administrador de contactos La aplicación de ejemplo es un simple administrador de contactos, tiene una lista de contactos y un formulario para añadir nuevos contactos. También, puede eliminar un contacto específico de la lista. El ejemplo muestra cómo funciona el marco de Ajax y cómo se puede utilizar los componentes Ajax RichFaces. También utiliza algunos componentes gráficos RichFaces como: rich:panel, rich:spacer, y rich:separator. Se utiliza el componente rich:calendar para la entrada de la fecha, y la versión RichFaces de dataTable (rich:dataTable y rich:column) con capacidad de filtrado automático y de ordenación. También usamos el componente de validación de Ajax (rich:beanValidator) para ajaxizar y mejorar la validación de JSF estándar. El tema (skin) que hemos elegido puede cambiar editando el nombre del tema en el archivo web.xml (veremos cómo hacer ésto en los capítulos siguientes).

Page 2: JBoss RichFaces. Capítulo 3. Primeros pasos.

Creación del nuevo proyecto Como hemos visto en el capítulo 2, preparándose, a fin de utilizar la seam-gen, abra una ventana de terminal y vaya al directorio de JBoss Seam. Desde aquí, podrá ejecutar comandos seam-gen. Antes de ejecutar el comando seam-gen que crea un proyecto nuevo, debemos configurarlo con los siguientes comandos. Si está utilizando Microsoft Windows, utilice el siguiente comando: seam setup Si usted está usando un sistema operativo tipo Unix como GNU/Linux o Mac OS X, use el siguiente comando: ./seam setup Después del texto de bienvenida, seam-gen nos hará algunas preguntas acerca de la configuración del proyecto, nos gustaría tener, para cada pregunta hay una respuesta por defecto (encerrada entre corchetes) que puede elegir pulsando la tecla Intro. Las preguntas no son difíciles de entender, vamos a ir a través de ellos y crear nuestro proyecto para el ejemplo: Pregunta Descripción Respuesta Introduzca el lugar de trabajo para sus proyectos de Java (el directorio que contiene sus proyectos de Seam)

Este es el directorio en el que queremos salvar nuestro nuevo proyecto (que depende de nuestro entorno y preferencias)

(La nueva ruta de directorio del proyecto)

Ingrese el directorio predeterminado de JBoss AS

Es el directorio donde está instalado el servidor de aplicaciones JBoss

(El directorio de JBoss)

Introduzca el nombre del proyecto

El nombre de la aplicación SimpleContactManager

¿Quieres usar ICEfaces en lugar de RichFaces [n]?

seam-gen también es compatible con ICEfaces (otro marco de componentes), pero queremos utilizar RichFaces, así que pulse Enter

No

Seleccione un tema para RichFaces [classic] (blueSky, [classic], deepMarine, DEFAULT, emeraldTown, japanCherry, ruby, wine)

Tenemos la opción de seleccionar cualquiera de los temas mostrados para nuestro proyecto, tambien podemos cambiarlo más tarde, por ahora, el tema classic esta bien

Solo presione Intro

Este proyecto es empaquetado como un EAR (con componentes EJB) o un WAR (sin soporte EJB) [ear]

Podemos generar un paquete WAR o un paquete EAR para nuestra aplicación. Nos gustaría una aplicación completa EAR con soporte EJB

Solo presione Intro

Introduzca el nombre del paquete Java para el beans de sesión

El nombre del paquete que contiene los beans de sesión (generado por seam-gen)

book.richfaces.scm

Introduzca el nombre del paquete de Java para su beans de entidad

El nombre del paquete que contiene los beans de entidad (generado por seam-gen)

book.richfaces.scm

Introduzca el nombre del paquete Java para los casos de prueba

El nombre del paquete que contiene los beans para nuestros casos de prueba

book.richfaces.scm.test

¿Qué tipo de base de datos se utiliza?

Por este simple ejemplo, no usamos ninguna base de datos

Solo presione Intro por defecto (hsql)

Introduzca el dialecto de Hibernate para la base de datos

No se utiliza en nuestro proyecto Solo presione Intro

Escriba la ruta del sistema No se utiliza en nuestro proyecto Solo presione Intro

Page 3: JBoss RichFaces. Capítulo 3. Primeros pasos.

para los controladores jar de JDBC Introduzca la clase para el controlador JDBC de la base de datos

No se utiliza en nuestro proyecto Solo presione Intro

Introduzca la dirección URL de conexión JDBC de la base de datos

No se utiliza en nuestro proyecto Solo presione Intro

Introduzca el nombre de la base de datos

No se utiliza en nuestro proyecto Solo presione Intro

Introduzca la contraseña de la base de datos

No se utiliza en nuestro proyecto Solo presione Intro

Introduzca el nombre del esquema de base de datos ( está bien dejar este espacio en blanco)

No se utiliza en nuestro proyecto Solo presione Intro

Introduzca el nombre de catálogo de base de datos (que está bien dejar este espacio en blanco)

No se utiliza en nuestro proyecto Solo presione Intro

¿Trabajar con las tablas que ya existen en la base de datos?

No se utiliza en nuestro proyecto Solo presione Intro

¿Quieres borrar y volver a crear las tablas de base de datos y los datos en Import.sql cada vez que se implante ?

No se utiliza en nuestro proyecto Solo presione Intro

Bien, hemos completado la configuración del proyecto. Vamos a ver cómo configurar un proyecto para la conexión a un DBMS MySQL en el capítulo 4, la Aplicación (cuando empezemos a hacer la aplicación real), por ahora está bien utilizar la opción predeterminada respuestas. Estamos listos para crear el proyecto utilizando los siguientes comandos. Si está utilizando Microsoft Windows, utilice el siguiente comando: seam create-project Si usted está usando un sistema operativo tipo Unix como GNU/Linux o Mac OS X, utilizar el siguiente comando: ./seam create-project Si está utilizando el IDE de Eclipse, tiene que importar el proyecto en el área de trabajo (se describe cómo hacer esto en el capítulo 2). Con otros IDE (como IntelliJ IDEA o NetBeans), puede abrir el proyecto en la ubicación especificada durante la ejecución de seam-gen.

Plantillas y Facelets Nuestro nuevo proyecto no sólo tiene el soporte de Facelets incluido, sino también un archivo de plantilla, en el que se puede editar para agregar nuestras características. Usted lo puede encontrar en la ruta /view/layout/template.xhtml. Esta es la estructura que usamos en otras páginas para evitar volver a escribir en varias ocasiones los mismos componentes en las demás páginas. Así es como se ve:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

Page 4: JBoss RichFaces. Capítulo 3. Primeros pasos.

<f:view contentType="text/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:a="http://richfaces.org/a4j" xmlns:s="http://jboss.com/products/seam/taglib"> <html> <head> <meta http-equiv="Content-Type" content="text/html;charset=UTF-8"/> <title>AdvContactManager</title> <link rel="shortcut icon" href="#{request.contextPath}/favicon.ico"/> <a:loadStyle src="resource:///stylesheet/theme.xcss"/> <a:loadStyle src="/stylesheet/theme.css"/> <ui:insert name="head"/> </head> <body> <ui:include src="menu.xhtml"> <ui:param name="projectName" value="AdvContactManager"/> </ui:include> <div class="body"> <h:messages id="messages" globalOnly="true" styleClass="message" errorClass="errormsg" infoClass="infomsg" warnClass="warnmsg" rendered="#{showGlobalMessages != 'false'}"/> <ui:insert name="body"/> </div> <div class="footer"> Powered by <a href="http://jboss.com/products/seam">Seam</a>. Generated by seam-gen. </div> </body> </html> </f:view>

Discutamos la página. Podemos ver la declaración DOCTYPE, que nos dice el tipo de documento que es, y después la etiqueta <f:view> con las declaraciones de espacio de nombres XML Facelets de las bibliotecas de componentes que vamos a utilizar. Tenga en cuenta que en esta página, no usamos los componentes RichFaces (todavía), únicamente está escrito el espacio de nombres para los componentes de Ajax4JSF (xmlns:a="http://richfaces.org/a4j". Esto es porque se utiliza la etiqueta <a:loadStyle>. Si desea utilizar los componentes RichFaces, tiene que incluir el correspondiente xmlns (el espacio de nombres necesario para poder utilizar todos los componentes RichFaces con el prefijo rich) como sigue: xmlns:rich=http://richfaces.org/Rich Vamos a insertarlo como queremos para utilizar los componentes RichFaces en la página template.xhtml.

Page 5: JBoss RichFaces. Capítulo 3. Primeros pasos.

Vamos a seguir analizando la página. Nuestro empieza documento (podemos ver las etiquetas <html>, <head>, <meta>, <title>, y <link>) después de la etiqueta <f:view>. Después de las etiquetas estándar, podemos ver <a:loadStyle>, que es un componente Ajax4jsf muy útil para hacer enlaces a la sección head de la página. Hay un componente llamado Facelets <ui:insert>. No vamos a explicar el marco Facelets en detalle, todo lo que tiene que saber es que el componente hace que los puntos de inserción con el fin de agregar el código de otras páginas, que utilizan esta plantilla. Por lo tanto, es muy útil para colocar el código en la sección head de otras páginas. Encontramos la etiqueta Facelets <ui:include> usada para incluir a otra página llamada menu.xhtml en la sección body. En el menú superior que puede ser utilizada para toda la aplicación. También pasamos dentro de la etiqueta ui:param, que incluye la página que puede que se puede usar (el parámetro es el nombre del proyecto en este caso). Ahora nos encontramos con un elemento div que contiene el componente estándar <h:messages>, el cual vamos a reemplazar con el componente RichFaces correspondiente. Debajo de la etiqueta h:messages, se encuentra el cuerpo Facelets del punto de inserción que es utilizada por otras páginas para insertar contenido específico (veremos cómo funciona esto en los párrafos siguientes). Al final del código, hay otra sección div, incluyendo algunos de texto con el enlace del sitio web de JBoss Seam.

Modificar el proyecto creado Para este ejemplo, sólo se utiliza una página y no aparece ningún menú, así que vamos a editar la página template.xhtml y eliminar la sección que incluye el menú en cada página: <ui:include src="menu.xhtml"> <ui:param name="projectName" value="AdvContactManager"/> </ui:include> Si queremos, también podemos personalizar el pie de página al cambiar el texto o borrarlo. Tenemos que cambiar el título de la página en la plantilla a Simple Contact Manager. Ahora abra el archivo home.xhtml para la edición, viene con el texto estándar de la presentación de la seam-gen. Vamos a eliminar la h1 sección y el componente rich:panel para tener una página en blanco. Además, podemos añadir el soporte para los componentes de Ajx4JSF mediante la inserción del espacio de nombres XML en la parte superior de la página. Ahora, la página tiene el siguiente aspecto: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <ui:composition xmlns="http://www.w3.org/1999/xhtml"

xmlns:s="http://jboss.com/products/seam/taglib" xmlns:ui="http://java.sun.com/jsf/facelets" xmlns:f="http://java.sun.com/jsf/core" xmlns:h="http://java.sun.com/jsf/html"

Page 6: JBoss RichFaces. Capítulo 3. Primeros pasos.

xmlns:a4j="https://ajax4jsf.dev.java.net/ajax" xmlns:rich="http://richfaces.org/rich"

template="layout/template.xhtml"> <ui:define name="body"> <!-- my code --> </ui:define> </ui:composition> Tenemos que agregar la estructura para hacer el formulario y la lista de contactos. Vamos a utilizar una etiqueta estándar h:panelGrid con dos columnas para este fin, así que vamos a colocar el siguiente código dentro de la sección body ( reemplazando el comentario <!-- my code -->):

<h3>Simple Contact Manager</h3> <rich:separator height="1" lineType="solid" width="100%"/> <h:panelGrid columns="2" width="100%" columnClasses="form-column, table-column"> <!-- Insert new contact form --> <!-- Contact list --> </h:panelGrid>

Como puede ver, también hemos añadido un encabezado (h3) y un espaciador entre el encabezado y h:panelGrid. También se utilizaron dos clases CSS para el panelGrid, pero no la hemos definido todavía. Por lo tanto, vamos a abrir el archivo theme.css dentro del directorio stylesheet. Puede ver algunas clases agregadas por seam-gen, no hay que hacerles caso y sólo agregue el código CSS siguiente al final del archivo:

form-column { vertical-align: top; width: 20%; } table-column { vertical-align: top; width: 80%; }

Esas clases simples CSS defininen el ancho de las dos columnas y alineación del contenido en la parte superior.

El modelo Tenemos que almacenar la información de contacto en una clase Java. En este caso, no tenemos el soporte de una base de datos y los datos permanecen en la memoria. En una aplicación real que vamos a desarrollar en los próximos capítulos vamos a usar MySQL. Por lo tanto, estaremos utilizando un sencillo Plain Old Java Object (POJO) para almacenar la información que necesitamos. Vamos a crear una clase de Java llamado ContactBean en el paquete book.richfaces.scm (carpeta src/main) e insertar el siguiente código: package book.richfaces.scm; import java.util.Date; public class ContactBean { private String name;

Page 7: JBoss RichFaces. Capítulo 3. Primeros pasos.

private String surname; private String email; private Date birthdate; public ContactBean() { } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getSurname() { return surname; } public void setSurname(String surname) { this.surname = surname; } public String getEmail() { return email; } public void setEmail(String email) { this.email = email; } public Date getBirthdate() { return birthdate; } public void setBirthdate(Date birthdate) { this.birthdate = birthdate; } } Como puede ver, esta es una simple clase Java con propiedades privadas, así como analizadores y modificadores públicos.

El bean administrado A fin de administrar las acciones de este ejemplo simple (como la inserción de un nuevo contacto, borrar un contacto, lista de todos los contactos), necesitamos un bean administrado. Podemos utilizar un bean administrado JSF estándar (lo que tenemos que haces es configurar el archivo faces-config.xml) o un componente de Seam y hemos elegido la segunda opción porque no tenemos que configurar nada durante el uso de un componente de Seam. Nos limitaremos a añadir una anotación a la clase que se va a utilizar (Seam simplifica el desarrollo de JSF). De todas formas, el código es simple y puede ser utilizado como un bean administrado estándar de JSF. Por lo tanto, vamos a crear una clase de Java llamado ContactsManager en el paquete de book.richfaces.scm (carpeta src/hot). Al principio, la clase está vacía: package book.richfaces.scm; public class ContactsManager { } En primer lugar, necesitamos un lugar para salvar a nuestra lista de contactos, una lista estándar de instancias ContactBean. Por lo tanto, vamos a agregar el código para su manejo: package book.richfaces.scm;

Page 8: JBoss RichFaces. Capítulo 3. Primeros pasos.

import java.util.ArrayList; import java.util.List; public class ContactsManager { private List<ContactBean> contactsList; public List<ContactBean> getContactsList() { if (contactsList==null) { contactsList=new ArrayList<ContactBean>(); } return contactsList; } public void setContactsList(List<ContactBean> contactsList) { this.contactsList = contactsList; } } Es una simple propiedad privada con un accesor y un modificador. El accesor inicializa lentamente la propiedad contactsList. Para insertar contactos, creamos una nueva instancia de ContactBean para conectar con el formulario Insertar nuevo contacto y una acción para insertarlo en la lista. Vamos a añadir el código que necesitamos dentro de la clase ContactsManager: private ContactBean newContact; public ContactBean getNewContact() { if (newContact==null) { newContact=new ContactBean(); } return newContact; } public void setNewContact(ContactBean newContact) { this.newContact = newContact; } public void insertContact() { getContactsList().add(0, getNewContact()); setNewContact(null); } Una vez más, tenemos la propiedad newContact con el accesor y modificador, y una acción insertContact.

Crear el bean administrado Como hemos dicho, con el fin de hacer la clase de un bean administrado, podemos utilizar la forma estándar de JSF o la forma de Seam. Le mostraremos la dos maneras, para que así usted pueda entender por qué el uso de Seam es más simple. Uso de la forma normal de JSF, tenemos que editar el archivo faces-config.xml para decirle JSF que la clase ContactsManager es un bean administrado. Tenemos que agregar el siguiente código dentro del elemento faces-config:

<managed-bean> <managed-bean-name>contactsManager</managed-bean-name>

Page 9: JBoss RichFaces. Capítulo 3. Primeros pasos.

<managed-bean-class> com.test.manager.ContactsManager </managed-bean-class> <managed-bean-scope>session</managed-bean-scope> </managed-bean>

No es un código difícil para todos, pero debe detallarse ya que tenemos que describir la clase, sus propiedades, y declarar el ámbito de aplicación de la clase (que es la sesión en este caso). Incluso si las herramientas nos ayudan a hacer esta tarea, manteniendo el archivo faces-config.xml es muy complicado. Uso de JBoss Seam, lo único que tienes que hacer es anotar la clase ContactsManager, que se convierte de esta manera:

package book.richfaces.scm; import java.util.ArrayList; import java.util.List; import org.jboss.seam.ScopeType; import org.jboss.seam.annotations.Name; import org.jboss.seam.annotations.Scope; @Name("contactsManager") @Scope(ScopeType.SESSION) public class ContactsManager { // code... }

En este caso, sólo se agregaron dos anotaciones, uno (@Name) esto dice a Seam que es un componente Seam (y también un bean administrado) llamado contactsManager, y el otro (@Scope) le dice a Seam que la clase tiene ámbito de sesión (por lo que se mantendrá en la memoria a través de las diversas solicitudes). No necesita modificar el archivo faces-config.xml y describir todos los campos de la clase. Simple, ¿no? Ahora estamos listos para escribir el XHTML y conectar con el bean administrado (podemos referirnos a ésta en XHTML utilizando su nombre, es decir contactsManager).

El formulario “Insertar nuevo contacto” Este es el formulario que le pide al usuario algunos datos y los inserta en la lista de contactos cuando el usuario hace clic en el botón Insertar. Todo esto se realiza mediante las llamadas a Ajax! Todos las validaciones de datos se realizan en Ajax al introducir los valores en los campos Nombre y Apellidos, y después de que el botón ha sido pulsado en los demás campos. Pero es sólo nuestra elección. Además, podemos aprovechar de las anotaciones Validator de Hibernate para establecer los validadores en los campos, utilizando el soporte para Ajax RichFaces Validator en f:validation (veremos cómo se hace esto en esta sección). Con el fin de mostrar otras funcionalidades Ajax, también queremos que el botón Insertar cambie el título, mientras el usuario está escribiendo su nombre y apellido. La captura de pantalla siguiente muestra el aspecto final que queremos para el formulario:

Page 10: JBoss RichFaces. Capítulo 3. Primeros pasos.

El formulario principal Para describir la caja del formulario, usamos un componente rich:panel con un encabezado. Dentro de él, ponemos un h:panelGrid con una columna para insertar campos, uno debajo del otro. Por lo tanto, tenemos el diseño del formulario listo, solo tienen que insertar este código en el archivo de home.xhtml (sustituir el comentario <!-- Insert new contact form -->):

<rich:panel> <f:facet name="header">Insert new contact</f:facet> <h:form id="fInsertContact"> <h:panelGrid columns="1"> <!-- fields --> </h:panelGrid> </h:form> </rich:panel>

Hemos declarado un panel simple con un encabezado utilizando el facet "header", al declararlo. Si el header es sólo texto, también puede utilizar el atributo de cabecera de esta manera: <rich:panel header="Header text"> ... </rich:panel>

Como puede ver, un panel es fácil de usar y puedes poner lo que quiera dentro de ella. Además, es totalmente personalizable mediante temas.

f:verbatim tag Es importante no usar f:verbatim para auto-contenedores, ya que es un componente transitorio y no se guardan en el árbol de componentes JSF.

Los campos del formulario Después de declarar el panel, tenemos que poner los campos en su interior, a fin de conectarlos a los beans administrados. Hemos declarado un bean administrado llamado contactsManager, que contiene una instancia de ContactBean (el bean que representa un contacto), distintos métodos para listar ,

Page 11: JBoss RichFaces. Capítulo 3. Primeros pasos.

insertar y eliminar contactos. Para insertar un nuevo contacto utilizamos newContact, vamos a conectar los campos a esta instancia (que está dentro del bean contactsManager). Aquí está el código para la descripción de los campos del formulario, inserta en el lugar del comentario <!--fields -->:

<h:outputLabel for="name" value="Name"/> <h:inputText id="name" value="#{contactsManager.newContact.name}" required="true"> <rich:beanValidator/> a4j:support event="onkeyup" timeout="200" ajaxSingle="true" reRender="insertButton"/> </h:inputText> <rich:message for="name" style="color: red;"/> <h:outputLabel for="surname" value="Surname"/> <h:inputText id="surname" value="#{contactsManager.newContact.surname}" required="true"> <rich:beanValidator/> <a4j:support event="onkeyup" timeout="200" ajaxSingle="true" reRender="insertButton"/> </h:inputText> <rich:message for="surname" style="color: red;"/> <h:outputLabel for="email" value="Email"/> <h:inputText id="email" value="#{contactsManager.newContact.email}" required="true"> <rich:beanValidator/> </h:inputText> <rich:message for="email" style="color: red;"/> <h:outputLabel for="birthdate" value="Birthdate"/> <rich:calendar id="birthdate" value="#{contactsManager.newContact.birthdate}" required="true"> <rich:beanValidator/> </rich:calendar> <rich:message for="birthdate" style="color: red;"/> <rich:spacer height="15"/> <rich:separator height="1" lineType="dotted" width="100%"/> <a4j:commandButton id="insertButton" action="#{contactsManager.insertContact}" value="Insert #{contactsManager.newContact.name} #{contactsManager. newContact.surname}" reRender="fInsertContact"/>

Como podemos ver, en el primer bloque de código (en el campo nombre) tenemos una etiqueta estándar de JSF h:outputLabel para la inserción de la etiqueta de la entrada y una etiqueta estándar h:inputText conectado al campo ContactBean con el atributo de valor. Después de eso, hemos utilizado rich:message en lugar del componente estándar h:message, ya que apoya AJAX fuera de la caja (y ofrece más personalización también). Consulte la siguiente sección para una mejor explicación.

Page 12: JBoss RichFaces. Capítulo 3. Primeros pasos.

Volviendo a h:inputText, podemos ver dos nuevas etiquetas, rich:beanValidator para la validación de campo Ajax y a4j:support para actualizar la imagen del botón Insertar mientras escribe.

Uso de mensajes RichFaces y componentes de mensajes en lugar de las estándar Al utilizar un componente est[andar h:message o h:messages, usted no recibe el JSF Ajax de mensajes de apoyo para los eventos JSF Ajax y los mensajes no se muestran después de un evento de AJAX. Con los componentes ricos rich:message y rich:messages, no tienes que preocuparte si estos trabajan con Ajax y peticiones JSF tradicionales. El uso básico es muy simple y es lo mismo que la estándar:

<rich:message for="myComponentId" /> Hacer una versión de Ajax de la componente estándar es sólo una parte de la labor del equipo RichFaces ha hecho en este componente. De hecho, añadieron una serie de características interesantes que se pueden utilizar para personalizar su aplicación. De hecho, proporcionan una mirada altamente personalizable y se sienten con soporte CSS. Además, puede personalizar cada parte de los componentes mediante la adición de una carilla para diferentes tipos de mensajes (WARN, INFO, FATAL, ERROR), y personalizar el "marcador" (por ejemplo, un icono) en consecuencia:

<rich:message for="myComponentId"> <f:facet name="warnMarker"> <h:graphicImage url="/images/warning.png"/> </f:facet> <f:facet name="errorMarker"> <h:graphicImage url="/images/error.png"/> </f:facet> <f:facet name="passedMarker"> <h:graphicImage url="/images/passed.png"/> </f:facet> </rich:message>

Además, puede agregar una cadena de texto passedLabel que se muestra cuando no hay mensaje de error.

Validación de nuestro campo de una manera sencilla Hay tres componentes JSF que puede utilizar para la validación. Vamos a ver en más detalle en el capítulo 4, la aplicación. Hemos utilizado los rich:beanValidator aquí, ya que utiliza el marco de Hibernate Validator para leer las reglas de validación directamente en el campo de ContactBean. De esta manera, no tenemos que escribir (y mantener!) los mismos validadores en diferentes campos, que se refieren a la misma entrada. En nuestro caso, podemos añadir anotaciones de Hibernate Validator a la clase del modelo (ContactBean).

Page 13: JBoss RichFaces. Capítulo 3. Primeros pasos.

rich:beanValidator lee y utiliza éstos para decidir la estrategia de validación; la clase ContactBean se define ahora como sigue:

public class ContactBean { private String name; private String surname; private String email; private Date birthdate; public ContactBean() { } @NotNull @Length(min = 3, max = 20) public String getName() { return name; } public void setName(String name) { this.name = name; } @NotNull @Length(min = 3, max = 20) public String getSurname() { return surname; } public void setSurname(String surname) { this.surname = surname; } @NotNull @Email public String getEmail() { return email; } public void setEmail(String email) { this.email = email; } @NotNull @Past public Date getBirthdate() { return birthdate; } public void setBirthdate(Date birthdate) { this.birthdate = birthdate; } }

No es el propósito de este libro para explicar cómo funciona el marco de Hibernate Validator, pero es sencillo de comprender desde el ejemplo. Si nos fijamos en el método getName, podemos ver las anotaciones @NotNull y @Length (este último con dos parámetros). Dicen rich:beanValidator que el campo no debe ser nulo, y que tiene una longitud mínima de dos caracteres y una longitud máxima de 20 caracteres. En el 99% de las solicitudes, sólo tenemos que anotar validadores para cada campo y ya está. De todos modos, siempre es posible agregar otro f:validator con rich:beanValidator con el fin de agregar reglas de validación específicos. Si nos fijamos en los otros campos de la clase ContactBean, podemos encontrar otros validadores como @Email y @Past. Hay otros que se pueden utilizar y usted puede incluso crear sus propios validadores para un propósito específico.

Page 14: JBoss RichFaces. Capítulo 3. Primeros pasos.

Agregar Ajax a componentes estándar de JSF: a4j:support Volviendo al código de forma, después de la etiqueta del validador, podemos ver otra etiqueta, a4j:support. Este es el componente más importante de Ajax de la biblioteca y lo coloca como un niño añade capacidades de Ajax para componentes estándar de JSF. El atributo event se utiliza para definir el evento de JavaScript que la solicitud se adjuntará el Ajax (en este caso, onkeyup que dispara un evento para todas las claves que el usuario). El atributo timeout describe el número de milisegundos (ms) para esperar antes de disparar la petición Ajax. En este caso, es útil para evitar una gran cantidad de peticiones Ajax, mientras el usuario está escribiendo. El atributo ajaxSingle cuenta el marco que acaba de enviar el valor del campo y no para enviar el formulario completo (sólo necesitamos la fecha que se incluirá en el campo, y los datos del formulario se presentará haciendo clic en el botón Insertar). Por último, el atributo reRender contiene el id (s) del componente JSF para "reRender" después de la petición Ajax. En este caso, queremos actualizar el título de la componente insertButton, que contiene el valor del campo (contactsManager. newContact.name) actualizado por la petición Ajax. Otro ejemplo se muestra como sigue:

<h:form> <h:inputText value="#{aBean.myText}"> <a4j:support event="onblur" reRender="out1" /> </h:inputText> </h:form> <h:outputText id="out1" value="#{aBean.myText}" />

Page 15: JBoss RichFaces. Capítulo 3. Primeros pasos.

Cuando el usuario pone un poco de texto dentro de inputText y presiona la tecla Tab o haga clic fuera del campo de entrada (onblur evento JavaScript), a4j:support actualizará la propiedad myText del grano aBean con el texto escrito. Luego se actualizará el outputText con id="out1". El campo Apellido obras como el campo Nombre, a diferencia del campo de correo electrónico no contiene a4j:support y se valida (siempre usando una petición Ajax) cuando el usuario hace clic en el botón Insertar (a4j:commandButton).

El campo Calendario En el cuarto campo, se utiliza el componente rich:calendar para obtener la fecha de nacimiento del contacto. Es muy simple de usar, pero tiene un montón de campos opcionales y pueden llegar a ser muy poderosos. Se puede utilizar para ajustar el tiempo también. Es totalmente personalizable, muestra una ventana emergente, y también trabaja con entrada manual. En la siguiente captura de pantalla, puede ver cómo aparece cuando el usuario hace clic en el icono de la derecha para seleccionar la fecha.

Tendremos en cuenta el uso de este componente con mayor profundidad en los capítulos siguientes.

Componentes de diseño simples: rich:separator y rich:spacer Esos son dos simples, pero los componentes de diseño de gran utilidad. Pueden mostrar una línea personalizables (por ejemplo, continuos, discontinuos, doble, y así sucesivamente) y personalizado (en tamaño), bloque vacío representa como una imagen transparente, respectivamente. El resultado HTML de la inserción de un elemento rich:separator con el atributo la height establecido en 1, el atributo width establecido a 100%, y el atributo lineType establecido a dotted es el siguiente:

<div class="rich-separator " style="height: 1px; width: 100%; background-image: url(/SimpleContactManager/a4j/g/3_2_2.SR1org. richfaces.renderkit.html.images.SimpleSeparatorImage/DATB/ eAFjYNxa6sUIAATTAXc_); null;"></div>

Page 16: JBoss RichFaces. Capítulo 3. Primeros pasos.

En lugar de utilizar el componente rich:separator, si se utiliza un componente rich:spacer con el atributo height establecido a 15, se obtiene el código XHTML:

<img class="rich-spacer " height="15" id="fInsertContact:j_id21" src="/SimpleContactManager/a4j/g/3_2_2.SR1images/spacer.gif" width="1" />

Botones de comando Ajax: a4j:commandButton El último componente que se puede ver en el código de campo del formulario es a4j:commandButton. Es la versión Ajax de h:commandButton y produce peticiones Ajax en lugar de los estándar, así como los atributos que tienen que gestionar las opciones de Ajax. El más importante es el atributo reRender que le dice al motor de JavaScript que área (s) de la página o componente debe ser actualizado después de una respuesta Ajax. Se puede volver a hacer uno o más componentes después de una petición Ajax. Se acepta un objeto String (un ID de componente o una coma lista de ID separados), Set, Collection, o Array (pasa a través de EL JSF). En nuestro código, se utiliza para llamar al método de acción (contactsManager.insertContact) que se inserta el grano newContact en el arreglo de la lista de contactos, a continuación, volver a revisualizar el formulario y la lista de contactos rich:dataTable. El formulario puede ser re-emitida para limpiar los campos (de hecho, después de la inserción, el método de contactsManager.insertContact limpia el campo para que podamos insertar otro contacto en una nueva instancia de ContactBean). Además, como se puede ver, el valor contiene el nombre y apellidos inserta. Por lo tanto, si el usuario escribe a John como el nombre y Wilson como el apellido, el valor del título de a4j:commandButton se convierte en "Insertar John Wilson", y gracias a a4j:support (como hemos visto en los párrafos anteriores), cambia mientras el usuario está escribiendo. He aquí otro ejemplo:

<h:form> <a4j:commandButton value="update" action="#{myBean. anOptionalAction}" reRender="block1,text1" </h:form> <h:panelGroup id="block1"> ... </h:panelGroup> <h:outputText id="text1" ... />

Cuando el usuario hace clic en el botón de actualización dictado por a4j:commandButton, el motor de JavaScript RichFaces hará una petición Ajax al servidor y esperar la respuesta. Después de eso, se actualizará los elementos block1 y text1. Tiene muchos más atributos útiles, que veremos en los capítulos siguientes.

Comandos de enlace Ajax: a4j:commandLink

Page 17: JBoss RichFaces. Capítulo 3. Primeros pasos.

Otra etiqueta útil es a4j:commandLink, que es la versión Ajax de h:commandLink. Funciona como a4j:commandButton, sino que hace un enlace (tag HTML) en lugar de el elemento de entrada. Es necesario mantenerlo dentro de la etiqueta h:form.

La lista de contactos Con el fin de mostrar (y permitir al usuario eliminar) la lista de contactos, que vamos a utilizar la versión RichFaces del clásico h:dataTable. Funciona de la misma manera, pero es muy útil y fácil de usar las características mejoradas. Se incluye en una etiqueta rich:panel (esta vez sin una cabecera, porque vamos a utilizar la de cabecera el facet rich:dataTable). También utilizaremos rich:datascoller para agregar paginación Ajax a los registros rich:dataTable y a4j:commandLink para agregar un botón para cada contacto en la lista. Usted puede ver el aspecto final en la siguiente captura de pantalla (el botón de borrar se muestra como un icono X en la última columna de la tabla.)

Aquí está el código que hay que añadir a su página home.xhtml ( reemplazar el comentario <!--Contact list -->) a fin de hacer la lista de contactos:

<rich:panel> <h:form id="fContactsList"> <rich:dataTable id="edtContactsList" value="#{contactsManager.contactsList}" var="contact" rows="5" width="100%"> <f:facet name="header">Contact List</f:facet> <rich:column sortBy="#{contact.name}" filterBy="#{contact.name}"> <f:facet name="header">Name</f:facet> <h:outputText value="#{contact.name}"/> </rich:column> <rich:column sortBy="#{contact.surname}" filterBy="#{contact.surname}"> <f:facet name="header">Surname</f:facet> <h:outputText value="#{contact.surname}"/> </rich:column> <rich:column sortBy="#{contact.email}" filterBy="#{contact.email}"> <f:facet name="header">Email</f:facet> <h:outputText value="#{contact.email}"/> </rich:column> <rich:column align="center"> <f:facet name="header">Birthdate</f:facet> <h:outputText value="#{contact.birthdate}"> <f:convertDateTime type="date" dateStyle="short"/> </h:outputText> </rich:column> </rich:dataTable>

Page 18: JBoss RichFaces. Capítulo 3. Primeros pasos.

<h:outputText value="No contacts found" rendered="#{empty contactsManager.contactsList}"/> <rich:datascroller id="dsContactsList" for="edtContactsList" renderIfSinglePage="false" /> </h:form> </rich:panel>

Como podemos ver, hemos usado una etiqueta rich:dataTable como una etiqueta h:dataTable estándar (De hecho, hemos utilizado el valor del parámetro var y rows, respectivamente, para establecer el arreglo de la lista de contactos. El parámetro de rows es la solicitud variable de alcance para manejar el objeto de la fila actual y el número de filas por página.). También hemos utilizado las versiones "ricas" de h:column, rich:column, con el fin de configurar el filtrado y funciones de ordenación para los campos nombre, apellido, y correo electrónico. La habilitación de la columna de base para la ordenación y filtrado es muy simple, sólo tienes que conectar los atributos sortBy y filterBy de rich:column con el campo que desea ordenar (o filtro).

No hay nada nuevo en el código. Hablaremos acerca de la "No hay contactos" valor de h:outputText en el siguiente capítulo (hablando de marcadores de posición Ajax). Después de ello, hemos insertado rich:datascroller y conectado a rich:dataTable utilizando el atributo for. El atributo renderIfSinglePage no visualizará el datascroller hasta que la tabla contenga al menos seis registros (uno más que el atributro rows de los rich:dataTable), lo que significa que serán dos páginas de datos.

Volver a visualizar la lista de contactos después de añadir un nuevo contacto En este punto, si tratamos de añadir un nuevo contacto, la lista de contactos no se actualizará. ¿Por qué? Esto es porque tenemos que decirle a insertButton que actualice no sólo la forma, sino también la lista de contactos después de ejecutar la acción. Con el fin de hacer eso, basta con modificar la propiedad reRender de insertButton añadiendo el id del formulario de la lista de contactos (fContactList), por lo que el componente aparece ahora como esta:

<a4j:commandButton id="insertButton" action="#{contactsManager.insertContact}" value="Insert #{contactsManager.newContact.name} #{contactsManager.newContact.surname}" reRender="fContactsList,fInsertContact" />

Page 19: JBoss RichFaces. Capítulo 3. Primeros pasos.

Ahora también se actualizará la lista de contactos que le mostrará el contacto acaba de insertar.

Agregando el botón de eliminar Nos gustaría añadir un botón de borrar como la última columna de la tabla. Con el fin de hacerlo, basta con insertar el código siguiente después de la columna birthdate: <rich:column width="50" align="center"> <f:facet name="header">Delete</f:facet> <a4j:commandLink reRender="fContactsList" action="#{contactsManager.deleteContact}"> <h:graphicImage style="border-width: 0px;" value="images/buttons/delete.gif" /> <f:setPropertyActionListener value="#{contact}" target="#{contactsManager.contactToDelete}"/> </a4j:commandLink> </rich:column> Se utilizó a4j:commandLink y una imagen (pero que debería haber utilizado el a4j:commandButton con el atributo graphicImage con la imagen correspondiente) para añadir agregar la funcionalidad de borrar los contactos. Este código es sencillo de entender. Cuando el usuario hace clic en el icono de supresión (es una X de color rojo), la variable contact (que apunta a la instancia ContactBean de la fila de la tabla seleccionada) se establecerá en la propiedad contactToDelete del bean contactsManager. Después de eso, la acción contactsManager.deleteContact será llamado y la instancia será removido de la lista de contactos. Tras la ejecución de la acción, en el marco RichFaces volverá a visualizar el formulario lista de contactos (de acuerdo con lo establecido en la propiedad reRender de a4j:commandLink) que muestra la nueva lista (sin la fila eliminada).

Resumen En este capítulo, se probó el poder de los componentes de RichFaces construir aplicaciones AJAX mediante el desarrollo de un ejemplo sencillo. Usted aprendió los fundamentos de RichFaces paso a paso, desde la creación del proyecto hasta la modificación del código, utilizando componentes muy importantes (como a4j:commandButton, a4j:commandLink, rich:dataTable, y rich:messages) y sus propiedades Ajax (por ejemplo , reRender). En el próximo capítulo, vamos a empezar a construir una aplicación real (un gestor de contactos avanzada), utilizando el marco en profundidad.