Reputation: 6633
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
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
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
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