ejemplo jsf primefaces datatable dialog master-detail

datatable jsf ejemplo



Cómo mostrar detalles de la fila actual de p: dataTable en ap: cuadro de diálogo y actualizar después de guardar (1)

Tengo una aplicación JSF 2 que tiene dos páginas, una para enumerar estudiantes y otra para mostrar detalles de un estudiante determinado. La página de listado tiene un enlace a la página de detalles en cada fila de la tabla de estudiantes, que abre una nueva pestaña en el navegador para mostrar esos detalles, cuando se hace clic.

Ahora los requisitos cambiaron a no mostrar más detalles en una nueva pestaña, sino en un diálogo modal en la página de listado.

Mi idea es simplemente insertar el contenido de la página de detalles en el cuadro de diálogo modal para que la página de listado no sea demasiado grande y difícil de mantener. Aquí comienzan mis dudas. Después de investigar un poco, cambié el enlace en cada fila de la lista al siguiente botón:

<p:commandButton value="Details" type="button" onclick="PF(''dialog-details'').show()"> </p:commandButton>

El diálogo se declara de la siguiente manera:

<p:dialog widgetVar="dialog-details" header="Details" modal="true" width="95%"> <ui:include src="student_details.xhtml"> <ui:param name="id" value="#{student.id}"/> </ui:include> </p:dialog>

Finalmente, la página de detalles fue cambiada para ser algo como esto:

<ui:composition xmlns="http://www.w3.org/1999/xhtml" xmlns:f="http://java.sun.com/jsf/core" xmlns:p="http://primefaces.org/ui" xmlns:h="http://java.sun.com/jsf/html" xmlns:ui="http://java.sun.com/jsf/facelets"> <f:metadata> <f:viewParam name="id" value="#{studentBean.id}" /> </f:metadata> <h1 class="title ui-widget-header ui-corner-all">Details of #{studentBean.bean.name} / #{studentBean.bean.number}</h1> </ui:composition>

Cuando hago clic en el botón, el cuadro de diálogo realmente se muestra y el contenido es la página de detalles. Veo el siguiente contenido en el cuadro de diálogo:

Details of /

No hay errores en absoluto, pero los datos que deberían mostrarse no lo son. Se estableció un punto de interrupción en StudentBean.setId() (este método carga una propiedad llamada bean con la instancia de Student correspondiente a la identificación pasada) pero nunca se golpea.

Después de pensarlo un tiempo, llegué a comprender por qué no funciona. El parámetro pasado a la página de detalles es student.id , pero student es el nombre utilizado como var en <p:datatable/> que muestra a todos los estudiantes, por lo que student no es válido en <p:dialog/> que está fuera la <p:datatable/> .

Entonces, lo que necesito es una forma de mostrar el diálogo utilizando la identificación del alumno correspondiente en una fila determinada. Idealmente, me gustaría una llamada ajax aquí, para que los detalles se carguen solo cuando sea necesario.

¿Algunas ideas?


El botón debe ser un botón ajax que establece la entidad iterada actualmente en el bean, y luego actualiza el contenido del diálogo y finalmente lo muestra. El cuadro de diálogo solo debe hacer referencia a esa entidad en el bean y actualizar la lista y la tabla al guardar.

Aquí hay un ejemplo inicial:

<h:form id="master"> <p:dataTable value="#{bean.entities}" var="entity"> <p:column>#{entity.property1}</p:column> <p:column>#{entity.property2}</p:column> <p:column>#{entity.property3}</p:column> ... <p:column> <p:commandButton value="View" action="#{bean.setEntity(entity)}" update=":detail" oncomplete="PF(''detail'').show()" /> </p:column> </p:dataTable> </h:form> <p:dialog id="detail" widgetVar="detail"> <h:form> <p:inputText value="#{bean.entity.property1}" /> <p:inputText value="#{bean.entity.property2}" /> <p:inputText value="#{bean.entity.property3}" /> ... <p:button value="Close" onclick="PF(''detail'').hide(); return false" /> <p:commandButton value="Save" action="#{bean.save}" update=":master" oncomplete="PF(''detail'').hide()" /> </h:form> </p:dialog>

Con esto dentro de un bean @ViewScoped :

private List<Entity> entities; // +getter private Entity entity; // +getter+setter @EJB private EntityService entityService; @PostConstruct public void load() { entities = entityService.list(); entity = null; } public void save() { entityService.save(entity); load(); }

Ver también: