Usando el componente PickList de Primefaces

Usando el componente PickList de Primefaces

0. Índice de contenidos.

1. Introducción

En este tutorial vamos a presentar el componente PickList de Primefaces, y cómo podemos aprovecharnos de su estructura para evitar realizar consultas innecesarias a base de datos en nuestros Converters. Además veremos como evitar algún bug de este componente, para que se comporte como realmente deseamos y esperamos.

Este componente nos ofrece la funcionalidad típica de disponer de dos listas a la que podemos ir ańadiendo o quitando elementos para pasarlos de una a otra sin tener que llevar nosotros el control de esto. Como ejemplo báse podéis mirar el showcase de primefaces.

Aquí os dejo una captura de pantalla de este componente para que veáis la funcionalidad que nos cubre:

2. Entorno

Este tutorial está escrito usando el siguiente entorno:

  • Hardware: Portátil MacBook Pro 15′ (2 GHz Intel Core i7, 8GB DDR3 SDRAM).
  • Sistema Operativo: Mac OS X Lion 10.7.1
  • Primefaces 2.2.1
  • JSF 2.1.2

3. Caso de ejemplo.

Aprovechando el inicio del mundial de rugby el 9 de septiembre vamos a hacer un poco de promoción de este magnífico deporte tán poco conocido por nuestro país. Así que el ejemplo consiste en elegir de cada grupo los equipos que se van a clasificar para la siguiente fase (sólamente hacemos la funcionalidad de pasar equipos de “eliminados” a “clasificados” y viceversa, sin validaciones de cuantos se pueden clasificar), aunque esto en realidad valdría para cualquier otro deporte.

Nuestras entidades serán:

Para los grupos:

Para Los equipos:

4. El DualListModel

Como todos los componentes, el PickList tiene una clase que define el componente (org.primefaces.component.picklist.PickList) y un renderer(org.primefaces.component.picklist.PickListRenderer) que encargado de pintar una instancia de la clase del componente. Además de esto, este componente hace uso de DualListModel (org.primefaces.model.DualListModel) que es donde nosotros realmente informaremos de cuáles son las dos listas con las que tiene que trabajar el componente.

Volviendo a nuestro caso de ejemplo, en nuestro controlador rellenaremos el DualListModel cuando se vaya a editar uno de los grupos, con los equipos del grupos seleccionado que tenemos en un mapa que rellenaremos al crear la vista.

Como podéis ver al DualListModel le pasamos directamente los objetos de nuestro modelo, que tendremos que convertir como veremos en el siguiente punto.

5. Converter accediendo al PickList

El componente PickList acepta en su atributo “converter” el identificador del conversor de los objetos que le pasamos. Estos objetos normalmente tendrán un conjunto de atributos entre los que estará un identificador que será el valor real en el HTML y el que se enviará al servidor para que con éste sepamos a que objeto concreto hace referencia. En nuestro ejemplo tenemos en el Equipo (Team), el identificador (identifier) y el nombre(name).

Comúnmente se recupera el objeto haciendo una consulta a base de datos pasando el identificador recibido; pero veremos que esto no es necesario, ya que ese objeto ya lo hemos tenido que recuperar antes para pintarlo en el componente, así que sólo tenemos que pedirle al componente que nos lo devuelva.

Para hacer esto nos crearemos el siguiente converter:

Como se puede ver, en el método getAsString(…) lo que hacemos es devolver el identificador del equipo igual que se hace comúnmente. Es en el método getAsObject(…) donde nos aprovechamos de la estructura del componente PickList para pedirle el objeto DualListModel y luego buscar en sus listas el equipo que se corresponde con la clave sin necesidad de ir a base de datos.

Finalmente en nuestro xhtml hacemos uso del componente PickList indicando el converter que acabamos de crear.

6. PickList en un contenedor

Como ya os avancé en la introducción, este componente nos evita gran parte del trabajo no teniendo que llevar el control de las listas, pero tiene algún problemilla. En nuestro caso lo sufrimos cuando reutilizábamos el componente en un DialogBox, que nos multiplicaba los elementos de la lista. Esto se producía al refrescar el contenido dependiendo de un parámetro, ya que en la primerqa ejecución funcionaba correctamente.

Al parecer, si el componente está en un contenedor, ya sea un DialogBox (<p:dialog>) o cualquier otro tipo de panel o contenedor, y lo que hacemos en la acción que selecciona el parámetro es enviar este parámetro al servidor y con su respuesta refrescar el contenedor que contiene al PickList, es cuando tenemos el problema. La solución pasaría por no refrescar el contenedor, si no los elementos del mismo que varían según la selección; además de esta forma podemos reducir el tama&nacute;o de la respuesta del servidor. Este bug está documentado en http://code.google.com/p/primefaces/issues/detail?id=2435.

En nuestro caso los distintos botones que de edición de los grupos para seleccionar los equipos que se clasifican los tenemos en un formulario. Cómo se puede ver no refrescamos en contenedor del PickList para evitar tener este problema, lo wque hacemos es refrescar el panel del nombre del grupo y el propio PickList.

7. Conclusiones

Bueno, pues como podéis ver hay muchos frameworks que nos ofrecen sus componentes con los que podemos trabajar, pero no tenemos que esperar que hagan todo el trabajo por nosotros. Así que si investigamos un poco como están hechos esos componentes podemos sacarles un mayor partido.

Por otro lado, tampoco hay que fiarse por completo de estos componentes ya que a veces tienen errores, aunque eso no signifique que no podamos usarlos, sólo hay que saber como evitar esos errores en nuestros proyectos. Así que es probable que en versiones más modernas ya estén corregidos y aprovecharnos de toda su potencia, además al ser la mayoría de ellos código abierto siempre podremos retocarlos a nuestra medida 😉

Espero que os sirva a alguno y ya sabéis, cualquier duda o sugerencia podeis comentarlo.

Saludos.