2013-03-07 31 views
1

如何從JSF 2中的bean有條件地調用JavaScript?有條件地從bean調用JavaScript

我有一個使用PrimeFaces上傳用戶文件到特定文件夾的類,但是如果用戶試圖上傳一個與已經存在的文件同名的文件,我希望JavaScript在這種情況下打開一個請求用戶是否要覆蓋舊文件或取消操作。如果不存在具有該名稱的文件,則不調用JavaScript。

我知道如何測試一個文件夾中有一個特定的文件,這只是我需要知道如何有條件地調用JavaScript。

我很感激任何意見。


我看過variopus資源在線,但仍然無法讓應用程序正常工作。基本上,這是我做了什麼,在包括XHTML頁面我對文件上傳下面的代碼:

<p:fileUpload id="fileUpload" fileUploadListener="#{filters.upload}" 
    allowTypes="#{filters.uploadTypes}" invalidFileMessage="#{filters.uploadBadType}" 
    sizeLimit="#{filters.uploadSize}" invalidSizeMessag="#{filters.uploadBadSize}" 
    update="fileUpload fileTable uploadMessage" description="Select Text File" 
    disabled="#{filters.disableFileUploadButton}"/> 

<!--- Then further in the same file is this: --> 

<p:remoteCommand name="remoteCommandOverwrite" actionListender="#{filters.execOverwrite}"/> 

父XHTML頁面,其中包括上面我有foolowing的JavaScript:

<script type="text/javascript"> 
    function popupConfirm() { 
    var overwrite = confirm('Warning: This will overwrite the existing file - Do you confirm this?'); 
    if (overwrite) remoteCommandOverwrite([{name: overwrite, value: true}]); 
    } 
</script> 

在我的豆我有三個方法如下代碼:

public void upload(FileUploadEvent event) { 
    FacesMessage msg = new FacesMessage("Success! ", event.getFile().getFileName() + " is uploaded."); 
    FacesContext.getCurrentInstance().addMessage(null, msg); 
    overwrite = false; 
    // Do what you want with the file   
    try { 
     copyFile(event.getFile().getFileName(), event.getFile().getInputstream()); 
    } catch (IOException e) { 
     e.printStackTrace(); 
    } 
} 

    public void copyFile(String fileName, InputStream in) { 

    // Initialization etc. 

        File file = new File(uploadFull + fileName); 
     if (file.exists()) { 
      RequestContext.getCurrentInstance().execute("popupConfirm()"); 

// Then test to see if overwrite is true or false, and act accordingly 

} 

// Then I am supposed to get the value of overwrite here: 
public void execOverwrite() { 
    System.out.println("### execOverwrite() ###"); 
    FacesContext context = FacesContext.getCurrentInstance(); 
    Map<String, String> map = context.getExternalContext().getRequestParameterMap(); 
    String soverwrite = (String) map.get("overwrite"); 
    if (soverwrite.equals("true")) { 
     overwrite = true; 
     System.out.println("overwrite: true"); 
    } 
} 

我所試圖做的是首先要有條件地調用JavaScript函數popupConfirm()。點擊「上傳」按鈕,如果密碼是真的,這是我想要的。然後這應該叫

這工作,並帶來了確認()框,但永遠不會被調用,所以我的bean中的方法execOverwrite()也永遠不會被調用,我不能拿起返回值和將它傳遞給方法copyFile()內的代碼。出了什麼問題?


我把這個問題擱置了一個星期,剛回到它。我得到它的工作,並可以將值傳回給bean,但不知何故,我需要從調用JavaScript的地方恢復執行。

要sumarize,我的JavaScript包含以下代碼:

<script type="text/javascript"> 
    function popupConfirm() { 
    var overwrite = confirm('Warning: This will overwrite the existing file - Do you confirm this?'); 
    if (overwrite) remoteCommandOverwrite([{name: 'overwrite', value: 'true'}]); 
    } 
</script> 

而在XHTML代碼我有:

<p:fileUpload id="fileUpload" fileUploadListener="#{filters.upload}" ...../> 

<!-- Other code --> 

<p:remoteCommand name="remoteCommandOverwrite" actionListener="#{filters.execOverwrite}"/> 

然後在單擊單擊選擇文件按鈕後,該文件的上傳按鈕,執行上面列出的JavaScript中的代碼:

RequestContext.getCurrentInstance().execute("popupConfirm()"); 

然後點擊在該對話框的「確定」,在同一個bean這種方法稱爲:

public void execOverwrite() { 
    FacesContext context = FacesContext.getCurrentInstance(); 
    Map<String, String> map = context.getExternalContext().getRequestParameterMap(); 
    String soverwrite = map.get("overwrite"); 
    if (soverwrite.equals("true")) { 
     overwrite = true;  } 
    } 
} 

該標誌「覆蓋」最終會被測試,看它是否是真實的。

使用各種打印語句我檢查這是否有效。但是,在遇到以下語句後,代碼不會繼續執行:RequestContext.getCurrentInstance()。執行( 「popupConfirm()」);不管我是否在對話框中輸入「確定」或「取消」,這正是我想要的。它看起來好像需要某種類型的回調,並且會很欣賞一些想法。

+0

我有與Primefaces 5.1和JSF 2.2.6相同的問題。 。你有解決方案嗎? – Marin 2014-11-26 15:51:11

回答

2

根據您的標籤,您正在使用PrimeFaces,所以當瀏覽器完成處理服務器響應時,可以通過服務器端事件託管bean方法調用JavaScript函數。 PrimeFaces爲您提供了一個名爲RequestContext的實用程序類。

public void doActionListenerMethod() { 
    if (!isValid()) { 
    RequestContext.getCurrentInstance().execute("MyJSObject.doClientSideStuff()"); 
    } 
} 

當JSF在客戶端上完成呈現時,以下將執行字符串參數作爲Javascript。

+0

好的,非常感謝,我得到了一個簡單的alert()框,可以作爲快速測試彈出。現在我需要使用出現的confirm()框,並根據用戶是否單擊「確定」或「取消」,文件被上傳或取消上傳。不知何故,這必須從JavaScript傳回給bean。 – csharp 2013-03-07 20:14:13

+0

@csharp那麼如果你使用PrimeFaces對話框,那麼你可以指定一個'widgetVar',它是一個Javascript變量,並且它們也有一個用於客戶端的'show()'和'hide()'函數。老實說,我可能會做的只是將文件立即上傳到會話變量中,以便它坐在服務器內存中。然後,我會在對話框內的一個表單中,將OK和Cancel按鈕作爲JSF commandButtons來調用服務器事件,以便保存文件或將其從會話上下文中取消。 ''的'oncomplete'屬性可以調用'hide()'JS函數 – 2013-03-07 20:30:43

+0

好的,這很有幫助,但我想盡可能簡單。如何從類似RequestContext.getCurrentInstance()的調用中返回一個值execute(「confirm('Warning:這將刪除所有上傳的文件 - 你確認這一點?')」);在「confirm()」框打開的位置,然後根據用戶的回覆方式返回true或false。我如何從RequestContext中獲取返回值,然後採取相應措施? – csharp 2013-03-08 11:29:52