2010-11-29 42 views
3

我目前有2個命令按鈕和一個列表框。根據列表框的選擇,生成的結果可以顯示在可下載的文件中或呈現爲HTML表格。 getFile()代碼基於BalusC's PDF Handling tutorial,而getTable()集合resultTableh:commandButton多個動作:下載文件並渲染ajax表

<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> 

到目前爲止,兩個按鈕都工作正常。但是,我想將這兩個操作合併到一個按鈕中。當我用一個觸發兩個動作的按鈕來測試時,沒有任何反應(沒有文件保存爲對話框或表格呈現)。這是因爲一個動作是ajax還是因爲其他動作完成了facesContext.responseComplete();

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

getBoth() { 
    getTable(); 
    getFile(); 
} 

此外,我想要一個複選框,如果它被選中,另存爲彈出對話框和表格呈現。如果未選中,則只顯示錶格。

回答

1

不幸的是,這在HTTP中不可行。每個請求只能發送一個響應。您不能將包含PDF文件和ajax響應的響應合併到一個響應中。由於這是一個HTTP限制,所以JSF不能爲你做任何事情。另外,使用Ajax下載文件根本不可能,因爲JavaScript不能強制瀏覽器彈出對話框,因爲安全限制,不能訪問本地磁盤文件系統。

解決方法是點擊兩個點擊一次按鈕上的HTTP請求,第二個請求返回Content-Disposition: attachment,以便其他請求的響應保持不變。您可以通過將onclick添加到命令按鈕來實現此目的。

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

並創建一個大致類似於this FileServlet example的PDF servlet。正如你所看到的,通過這個調用JSF動作是不可能的。您必須將PDF下載方法重構爲HttpServlet類,該類可完成doGet()方法中的工作。對於JSF託管bean和servlet之間的任何必要通信,您可以使用會話範圍或通過請求路徑或參數傳遞所需的信息(只是PDF文件標識符?)。

+0

感謝您的解釋。我將繼續使用這兩個按鈕。 – luciaengel 2010-11-29 13:48:49

0

我傳遞了一個類似的情況,在我的情況下,我使用ajax richfaces標記庫和環繞命令按鈕與ajax窗體標記解決。

<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>