primeface eventos etiqueta ejemplos java ajax jsf jsf-2 facelets

java - eventos - jsf events



h: acciones mĂșltiples CommandButton: descargar archivo y renderizar una tabla ajax (2)

Actualmente tengo 2 botones de comando y un cuadro de lista. En función de la selección del cuadro de lista, el resultado generado puede mostrarse en un archivo descargable o representarse como una tabla HTML. El código getFile() se basa en el tutorial PDF Handling de getTable() , mientras que getTable() establece resultTable .

<h:form> <fieldset> <h:selectManyListbox id="listbox" value="#{form.items}"> <f:selectItems value="#{form.allItems}"> </h:selectManyListbox> </fieldset> <h:commandButton value="Get File" action="#{form.getFile}"> <h:commandButton value="Get Table" action="#{form.getTable}"> <f:ajax render="result_table" execute="listbox" /> </h:commandButton> <h:panelGrid id="result_table"> <table> <thead></thead> <tbody> <ui:repeat var="table" value="#{form.resultTable}"> </ui:repeat> </tbody> </table> </h:panelGrid>

Ambos botones funcionan bien hasta el momento. Sin embargo, quiero combinar ambas acciones en un solo botón. Cuando pruebo esto con un botón que activa ambas acciones, no ocurre nada (no se guarda el archivo como un cuadro de diálogo o una tabla). Esto es porque una acción es ajax o porque la otra acción termina con facesContext.responseComplete(); ?

<h:commandButton value="Get Both" action="#{form.getBoth}"> <f:ajax render="result_table" execute="listbox" /> </h:commandButton> getBoth() { getTable(); getFile(); }

Además, quisiera una casilla de verificación donde, si está marcada, la guarde a medida que aparece el cuadro de diálogo y se muestra la tabla. Si no está marcado, solo se procesará la tabla.


Desafortunadamente, eso no es posible con HTTP. Puede enviar solo una respuesta por solicitud. No puede combinar la respuesta que contiene el archivo PDF y la respuesta ajax en una sola respuesta. Como se trata de una restricción HTTP, JSF no puede hacer mucho por usted. Además, la descarga de un archivo con Ajax no es posible en absoluto, ya que JavaScript no puede obligar al navegador a mostrar un diálogo Guardar como ni tener acceso al sistema de archivos del disco local debido a restricciones de seguridad.

Una solución sería disparar dos solicitudes HTTP con un solo clic, donde la segunda solicitud devuelve Content-Disposition: attachment para que la respuesta de la otra solicitud permanezca intacta. Puede lograr esto agregando un clic en el botón de comando.

<h:commandButton onclick="window.location=''/context/pdfservlet/filename.pdf''">

y cree un servlet PDF que se parezca más o menos a este ejemplo de FileServlet . Como ve, no es posible invocar una acción JSF por esto. Tiene que refactorizar el método de descarga de PDF a una clase HttpServlet que hace el trabajo en el método doGet() . Para cualquier comunicación necesaria entre el bean gestionado JSF y el servlet, puede usar el alcance de sesión o pasar la información deseada (¿solo el identificador de archivo PDF?) Por ruta o parámetro de solicitud.


Paso por un caso similar, en mi caso me resuelvo usando ajax richfaces tag lib y rodear commandbuton con ajax form tag.

<ui:composition xmlns="http://www.w3.org/1999/xhtml" xmlns:rich="http://richfaces.org/rich" xmlns:a4j="http://richfaces.org/a4j"> <a4j:form id="formDownloads"> <rich:panel> <h:commandButton value="Exportar para PDF" status= "block" ... /> </rich:panel> </a4j:form>