【问题标题】:PrimeFaces p:fileUpload multiple files autoComplete only works after first filePrimeFaces p:fileUpload multiple files autoComplete 仅在第一个文件后有效
【发布时间】:2012-08-11 17:01:22
【问题描述】:

我尝试上传一些文件,然后通过oncomplete 重定向到另一个页面 问题是oncomplete 仅在第一个文件上传后才起作用

<p:fileUpload  mode="advanced"
     label="#{FileMessages.file_add_file_lbl_Select_File}"
     fileUploadListener="#{fileAddFileAction.upload}"
     oncomplete="redirect(#{fileAddFileAction.groupId});"
     multiple="true"
     allowTypes="/(\.|\/)(txt|doc|docx|pdf)$/"
     widgetVar="fileUplaod" >
 </p:fileUpload>

Java 脚本函数:redirect(groupId)

function redirect(groupId) {
     var url = "/network/group/files.html?gId="+groupId;
     $(location).attr('href',url);
}

bean.java

public void upload(FileUploadEvent event) {

    UploadedFile uploadedFile = event.getFile();

    try {
        String thumbnail = getDestination() + uploadedFile.getFileName();
        String[] filetype = thumbnail.split("\\.");
        String newfilename = Calendar.getInstance().getTimeInMillis() + "." + filetype[1];

        SystemFile file = new SystemFile();
        file.setAccount(getActor().getAccount());
        file.setCtime(new Date());
        file.setName(newfilename);
        file.setPath(getDestination());
        file.setFileType(FileUtil.checkFileType(filetype[1]));
        file.setOriginalName(uploadedFile.getFileName());

        getFileService().saveSystemFile(file);

        copyFile(getDestination() + newfilename, uploadedFile.getInputstream());

        copyFile(getDestination() + newfilename, uploadedFile.getInputstream());

    } catch (IOException ex) {
        Logger.getLogger(FileAddFileAction.class.getName()).log(Level.SEVERE, null, ex);
    }
}

【问题讨论】:

    标签: javascript jquery jsf primefaces javabeans


    【解决方案1】:

    这似乎是一个已知问题:http://code.google.com/p/primefaces/issues/detail?id=3836

    用户已在此页面上完成了自定义补丁:

    可以通过在 p:fileUpload 标签中添加以下行来使用它:

    <p:ajax event="fileUploadsComplete" listener="#{filesBean.done}"/>
    

    filesBean.done 方法如下所示:

    public void done(FileUploadsCompleteEvent event) {
        System.out.println("done"); 
    }
    

    【讨论】:

      【解决方案2】:

      我遇到了类似的问题(Primefaces 5)。由于“父级不是 ClientBehaviorHolder 的实例”错误,添加 ajax 文件上传完成失败。

      这是我的小窍门。这不是最令人满意的,但它正在工作:

      <script>
          function setUploadFilesCount() {
              var numberOfFiles = $('.ui-fileupload-preview').size();
              var input = document.getElementById('fileupload-multi-fix-input');
              input.value = numberOfFiles;
              input.onchange();
          }
      </script>
      
      <h:form id="file-upload-form">
          <p:fileUpload id="file-upload" fileUploadListener="#{backingBean.handleFilesUpload}" mode="advanced" dragDropSupport="false"
                                     sizeLimit="10000000" multiple="true" allowTypes="/(\.|\/)(jpg)$/" onstart="setUploadFilesCount()" update=":content">
          </p:fileUpload>
      </h:form>
      
      <h:form prependId="false" style="display:none;">
          <h:inputText id="fileupload-multi-fix-input" value="#{backingBean.numberOfUploadFiles}">
              <f:ajax event="change" execute="@form"  />
          </h:inputText>
      </h:form>
      

      所以在我的 BackingBean 中我有以下内容:

      @Named
      @SessionScoped
      public class BackingBean implements Serializable{
      
          private static final long serialVersionUID = 1L;
      
          private int numberOfUploadFiles; //... add getter and setter
      
          private boolean isUploadComplete = false; //... add getter and setter
      
          private int uploadCount = 0;
      
          public void handleFilesUpload(FileUploadEvent event) throws IOException {
      
              // ... handle file upload here
      
              uploadCount++;
      
              if(uploadCount == numberOfUploadFiles){
                  isUploadComplete = true;
              }
          }
      }
      

      解释:

      我添加了一个 JavaScript 函数 setUploadFilesCount 和第二个 &lt;h:form /&gt;,其中包含一个隐藏的 &lt;h:input /&gt;

      &lt;p:fileUpload onstart=... 在(第一个)文件传输开始时被调用一次。 我在onstart 中调用JavaScript 函数setUploadFilesCount 来设置支持bean 中上传文件的数量。

      通过读取css类ui-fileupload-preview的元素的出现次数来检测文件数。视图中ui-fileupload-preview 元素的数量等于上传文件的数量。这发生在

      $('.ui-fileupload-preview').size();
      

      input.onchange(); 使隐藏的输入字段值提交给支持 bean。

      在 backing bean 上,我可以通过增加一个计数器来检查最后一个项目是否已上传

      uploadCount++;
      
      if(uploadCount == numberOfUploadFiles){...}
      

      所以我可以检查是否所有项目都已上传或在最后一个上传项目完成后调用特殊函数。


      &lt;p:fileUpload oncomplete... 每次上传一个上传文件时都会被调用。

      因此,在您的特定情况下,您必须另外将您的 javascript 包装成这样:

      <h:panelGroup id="afterLoad">
          <h:outputScript>
              function redirect(groupId) {
                  if(#{backingBean.isUploadComplete}=='true'){
                      var url = "/network/group/files.html?gId="+groupId;
                      $(location).attr('href',url);
                  }
              }
          </h:outputScript>
      </h:panelGroup>
      

      把它和&lt;p:fileUpload一样的形式加上&lt;p:fileUpload ... update="afterLoad" ...

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-01-29
        • 2012-04-15
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多