2013-03-07 35 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