Uso del componente remoteCommand de primefaces para actualizar el contenedor de un componente de lightBox en modo iframe

3
34589

Uso del componente remoteCommand de primefaces para actualizar el contenedor de un componente de lightBox en modo iframe.

0. Índice de contenidos.


1. Introducción

Hay tutoriales de próposito general, unos más técnicos otros menos y otros, como este, que tienen una temática muy concreta. El propósito de este tutorial es mostrar como solucionar un problema que nos encontramos con Primefaces haciendo uso del componente lightBox en modo iframe.

El componente de lightBox de Primefaces nos permite mostrar una ventana modal con un contenido predeterminado oscureciendo el resto de la pantalla. Además, tenemos la posibilidad de parametrizarlo para que el contenido de la ventana no forme parte del árbol de componentes de la página que lo contiene; con el modo iframe, como su nombre indica, se crea un iframe, con lo que se realiza una nueva petición que tiene su propio ciclo de vida y, si el fuente a cargar es un recurso jsf, se crea un árbol de componentes distinto para el contenido del iframe.

Con ello, tendríamos dos árboles de componentes que manejar y el problema viene cuando desde el contenido del iframe queremos provocar un evento que se propague al árbol que lo contiene como, por ejemplo, para actualizar de forma asíncrona parte del mismo.

El ejemplo podría ser el de una ventana de selección, en la que se muestra un listado y nuestro objetivo es que al pulsar sobre una de las filas, además de cerrarse la ventana, se asigne el valor seleccionado a un componente de la página que lo contiene.


2. Entorno.

El tutorial está escrito usando el siguiente entorno:

  • Hardware: Portátil MacBook Pro 17′ (2.93 GHz Intel Core 2 Duo, 4GB DDR3 SDRAM).
  • Sistema Operativo: Mac OS X Snow Leopard 10.6.1
  • Primefaces 2.2.1
  • JSF 2 – Mojarra-2.0.3


3. Inclusión de un componente lightBox de tipo iframe.

Para añadir un componente lightBox de tipo iframe a nuestro árbol debemos incluir un código como el que sigue:

	<p:lightBox width="85%" height="85%" iframe="true" widgetVar="selectIframe" >  
		<h:outputLink value="sectionSelector.xhtml" >  
			<h:outputText value="#{msg['action.sectionSelector']}"/>  
		</h:outputLink>
	</p:lightBox>

El componente visual contenido dentro del outputLink es quien desencadenará el evento de mostrar la ventana modal, en nuestro caso un simple texto que se mostrará como un enlace.

El contenido de la ventana viene dado por el valor del atributo value del outputLink, me modo que si necesitamos cargar una página externa bastará con incluir la url a la misma y si queremos cargar una página jsf, del mismo modo, podemos incluir una url relativa. En nuestro caso se cargará la página sectionSelector.xhtml que contiene un árbol de componentes JSF.


4. Controlar un evento para actualizar el árbol que lo contiene mediante el componente remoteCommand.

Si, como hemos comentado, en el contenido de la ventana modal quisieramos incluir un evento sobre un botón o un enlace que provocase el cierre de la ventana y la actualización parcial del árbol de componentes JSF que contiene el lightBox, esto es, su contenedor, podríamos incluir un código como el que sigue:

	<p:commandLink ajax="true" immediate="true" action="#{myView.addSection(section)}" 
		title="#{msg['action.select']}" 
		oncomplete="parent.refreshSections();parent.jQuery.fn.colorbox.close();">
		<h:graphicImage value="#{resource['images:selection.png']}"/> 
	</p:commandLink>		 

Se trata de un enlace que provoca la ejecución de un método de acción en el managedBean myView que recibe un parámetro puesto que disponemos del soporte de EL 2.2, después de ejecutarse el evento se invocan a un par de funciones javascript definidas en la página contenedora del iframe, en el parent:.

  • parent.refreshSections();: que veremos a continuación como la definiremos, y que actualizará de forma asíncrona el árbol de componentes JSF de la página contenedora del iframe,
  • parent.jQuery.fn.colorbox.close();: que cierra el ligthbox,

Para definir la función refreshSections(); en la página contedora vamos a incluir un código como el que sigue:

	<p:remoteCommand name="refreshSections" update="panelSections" />
	<p:panel id="panelSections" widgetVar="panelSections">
	...
	</p:panel>

Hacemos uso del componente remoteCommand de primefaces que nos permite la «publicación» de una función en javascript que provoca la incovación a un método en el controlador y que, además, permite programar la rerenderización de parte de árbol de forma asíncrona. Nosotros no hemos programado la llamada a ningún método en el controlador porque no lo necesitamos, simplemente hemos definido que cuando se produzca el evento de llamada a la función se repinte el panel de secciones.

Para que lo entendamos mejor, la renderización de ese componente en html sería similar a la siguiente:

<script type="text/javascript">refreshSections = function() {PrimeFaces.ajax.AjaxRequest('/pages/sections/edit.xhtml',{formId:'myForm',async:false,global:true,source:'myForm:j_idt54',process:'@all',update:'myForm:panelSections'});}</script>

Con ello, como hemos hecho, desde cualquier función javascript invocando a refreshSections() se repinta dicho panel o se invocaría a un método en el control si así lo hubiésemos programado.


5. Referencias.

  • http://www.primefaces.org/showcase/ui/lightBoxExternal.jsf
  • http://www.primefaces.org/showcase/ui/remoteCommand.jsf
  • http://primefaces.prime.com.tr/forum/viewtopic.php?f=3&t=11792&p=37971#p37971


7. Conclusiones.

Algo complejo, pero no imposible. Y es que hay veces que tenemos que llegar a este nivel para controlar lo que el framework, la mayoría de las veces, controla por nosotros.

Entiendo que no es una temática que resulte de utilidad a muchos, pero con que le sirva a uno nos basta. Eso sí, qué al menos nos escriba contándonoslo 😉

Un saludo.

Jose

jmsanchez@autentia.com

3 COMENTARIOS

  1. Hola Buen Dia: Me encuentro trabajando sobre Java Server faces 3.4, mojarra 2.1 y JBoss 7.1 y eclipse juno 4.1 y mi problema es que tengo y pues en la clase \\\»miclase\\\» tengo el metodo \\\»mi metodo\\\» pero al intentar llamar al metodo \\\»mimetodo\\\» desde el home.xhtml no puedo o eclipse no me permite verlo… no se si es por el tipo de bean que tengo o no es la etiqueta correcta para llamar o no es el atributo de la etiqueta… gracias por su colaboracion.

  2. interesante, entiendo que es del Hijo(iframe) al padre(home), es posible actualizar algun comonente del Hijo(iframe) desde el padre??? gracias por su ayuda

  3. Muchas gracias por este post, me ayudó mucho, no podia actualizar un panelgrid desde un dialog
    al agregar elementos al grid actualizaba bien en forma descendente , pero si agregaba de forma intercalada no actualizaba correctamente

    <p:remoteCommand lo solucionó al llamarlo en onsuccess del dialog

DEJA UNA RESPUESTA

Por favor ingrese su comentario!

He leído y acepto la política de privacidad

Por favor ingrese su nombre aquí

Información básica acerca de la protección de datos

  • Responsable:
  • Finalidad:
  • Legitimación:
  • Destinatarios:
  • Derechos:
  • Más información: Puedes ampliar información acerca de la protección de datos en el siguiente enlace:política de privacidad