BRabbit27
BRabbit27

Reputation: 6633

PrimeFaces number of files in FileUpload

I'm very new to PrimeFaces components. I have a FileUpload (multiple files uploaded) and I want to know if there's a way to know how many files are in the upload component before uploading them. What I need is to upload 1 to 6 files and just after the 6th is uploaded process the all the files. Any idea on how can I achieve this is very welcome.

Cheers

UPDATE Already tried with oncomplete but it does not help me 'cause this event is executed every time a file is uploaded not 'till all files are.

Upvotes: 6

Views: 4128

Answers (3)

swist
swist

Reputation: 1171

I've modified the Aleksandr's answer to simplify the onstart command, by the price of more complicated Java part.

</div>
  <p:fileUpload widgetVar="importFile" listener="#{fileUploadView.handleFileUpload}" dragDropSupport="true" mode="advanced" multiple="true"
                        onstart="rc([{name:'size', value:PF('importFile').files.length}])"/>
  <p:remoteCommand name="rc" update="messages" actionListener="#{fileUploadView.setSize}" />
</div>

and

@Named
@ViewScoped
public class FileUploadView {

  private AtomicInteger size = new AtomicInteger();

  private List<UploadedFile> files = new ArrayList<>();

  public void setSize(ActionEvent e) {
    String length  = e.getFacesContext().getExternalContext().getRequestParameterMap().get("size");
    if(length != null) {
      size.set(Integer.parseInt(length));
    }
  }
  public void handleFileUpload(FileUploadEvent event) {
    files.add(event.getFile());
    if(size.decrementAndGet() == 0) {
      FacesMessage msg = new FacesMessage("Successful", files.size() + " uploaded");
      FacesContext.getCurrentInstance().addMessage(null, msg);
      files.clear();
    }
  }
}

Upvotes: 0

Aleksandr Erokhin
Aleksandr Erokhin

Reputation: 1982

Ok, this is pretty old thread but I've found straitforward way to determine the number of files been uploaded.

p:fileUpload widget has an array with meta-info about selected files. By passing the length of this array to your bean you will obtain the total number of files.

There is a problem though: p:fileUpload doesn't submit the surrounding form, so I had to put invisible button along with the h:inputHidden to pass the number of files from JavaScript to ManagedBean:

<h:form id="importDlgForm">
    <p:fileUpload id="importFile" widgetVar="importFile" fileUploadListener="#{importDialogView.importFile}"
                      mode="advanced" multiple="true"
                      onstart="$('#importDlgForm\\:file_number_input').val(PF('importFile').files.length);
                      $('#importDlgForm\\:submit_btn').click();"/>
    <h:inputHidden id="file_number_input" value="#{importDialogView.importFileNumber}"/>
    <p:commandButton id="submit_btn" style="display: none"/>
</h:form>

I also had to use AtomicInteger in order to track processed files, as p:fileUpload uses multiple threads to upload files by default.

private final AtomicInteger atomicImportFileNumber = new AtomicInteger();
private Integer importFileNumber;

public Integer getImportFileNumber() {
    return importFileNumber;
}

public void setImportFileNumber(Integer importFileNumber) {
    this.importFileNumber = importFileNumber;
    atomicImportFileNumber.set(importFileNumber);
}

public void importFile(FileUploadEvent event) {
    // common file upload stuff
    if (atomicImportFileNumber.decrementAndGet() == 0) {
        // part to execute only when all files have been uploaded   
    }
}

Upvotes: 5

spauny
spauny

Reputation: 5116

If you want to upload all the files, all 6 of them at once or only 1 at a time, and then call a processing message, you have to create a variable or better a list where you insert the name of each file, or even the file objects and when the ArrayList size reach 6 you call a processing method. Simple as that!

private ArrayList<UploadedFile> listWithUploadedFile = new ArrayList<UploadedFile>();
public void uploadMethod(){
//upload file, save input stream and any other thing you want
  listWithUploadedFile.add(file);
  if(listWithUploadedFile.size==6){
    myProcessUploadedFilesMethod();
  }
}

Upvotes: 1

Related Questions