检查是否在p:fileUpload中选择了一个文件

Rap*_*oth 2 jsf file-upload primefaces

我正在使用PrimeFaces的简单fileUpload和自定义提交按钮,如下所示:

<h:form enctype="multipart/form-data">

    <p:fileUpload value="#{fileController.file}"
                  mode="simple"
                  skinSimple="true"
                  label="choose file"/>

    <p:commandButton value="upload"
                     ajax="false"
                     label="upload"
                     icon="fa fa-upload"
                     actionListener="#{fileController.upload}"/>
</h:form>
Run Code Online (Sandbox Code Playgroud)

在backing bean中,file是一个类型的属性UploadedFile.

现在我想要upload在没有选择文件的情况下禁用该按钮,但是我无法获得信息,无论用户是否选择了文件,file属性都会保留,null直到upload单击该按钮为止.我试过valueChangeListener的上<p:fileUpload>部件,但是当我点击上传按钮的事件仅触发(但后来为时已晚)

有人有建议吗?

Bal*_*usC 8

你最终需要一个关于HTML DOM change事件的钩子<input type="file">.没有ajax(via <p:ajax>)<p:fileUpload mode="simple">因为两个原因而变得棘手:

  • 它不支持onchange属性.PF人员可能值得一个增强请求.幸运的是,从JSF 2.2开始,您可以指定直通属性.
  • skinSimple="true"生成a <span><span><input /></span></span>并且passthrough属性将onchange在所有这些元素上呈现.如果this<input>元素,您需要额外检查.

总而言之,这是如何做到的:

<html ... xmlns:a="http://xmlns.jcp.org/jsf/passthrough">
...
<h:form enctype="multipart/form-data">
    <p:fileUpload label="choose file" mode="simple" skinSimple="true"
        value="#{bean.file}"
        a:onchange="if (tagName == 'INPUT') { if (!!value) PF('button').enable(); else PF('button').disable(); }" />

    <p:commandButton widgetVar="button" value="upload" 
        action="#{bean.upload}" ajax="false"
        disabled="#{facesContext.renderResponse or not facesContext.postback}" />
</h:form>
Run Code Online (Sandbox Code Playgroud)

disabled按钮属性中的条件确保仅在呈现响应阶段和初始GET请求期间禁用它.否则,JSF将拒绝按照commandButton/commandLink/ajax动作/侦听器方法的第 5点对动作事件进行排队,或者未调用输入值.

按钮被绑定到该文档作为widgetVar使得JS可以启用/经由其禁用它enable()disable()功能.