I have an issue when uploading a file using the PrimeFaces fileUpload control.
The problem is that the upload event is being called 4 times when I upload a file.
I cannot find a clear reason on this.
Here's my xhtml page:
<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:p="http://primefaces.org/ui"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:ui="http://java.sun.com/jsf/facelets">
<h:head>
</h:head>
<h:body>
<ui:composition template="home.xhtml">
<ui:define name="content">
<script type="text/javascript">
function callChangeImage(){
alert('completed');
var hiddenLink = document.getElementById('mainForm:hiddenLink');
hiddenLink.click();
}
function callDeleteImageFromTemp(){
alert('started');
updated = false;
var hiddenLink2 = document.getElementById('mainForm:hiddenLink2');
hiddenLink2.click();
}
</script>
<p>
<p:commandButton value="Agregar Noticia" update="newsTable, display" icon="ui-icon-circle-plus" actionListener="#{newsBean.addNew}" oncomplete="newDialog.show()"/>
<p:commandButton value="Editar Noticia" oncomplete="editNewDialog.show()" icon="ui-icon-pencil"/>
<p:commandButton value ="Eliminar Noticia" icon="ui-icon-trash" onclick="dlgDelete.show()" />
</p>
<p:scrollPanel>
<p:dataTable var="unew" value="#{newsBean.news}" rowKey="#{unew.id}"
selection="#{newsBean.selectedNew}" selectionMode="single" id="newsTable">
<p:ajax event="rowSelect" update=":mainForm:display" />
<f:facet name="header">
Lista de noticias
</f:facet>
<p:column headerText="Numero" sortBy="#{unew.id}" filterBy="#{unew.id}" id="id">
#{unew.id}
</p:column>
<p:column headerText="Titulo" sortBy="#{unew.title}" filterBy="#{unew.title}" id="title">
#{unew.title}
</p:column>
<p:column headerText="Descripcion" sortBy="#{unew.description}" filterBy="#{unew.description}" id="description">
#{unew.description}
</p:column>
<p:column headerText="Enlace" sortBy="#{unew.link}" filterBy="#{unew.link}" id="link">
#{unew.link}
</p:column>
<p:column headerText="Imagen" sortBy="#{unew.img}" filterBy="#{unew.img}" id="img">
#{unew.img}
</p:column>
</p:dataTable>
</p:scrollPanel>
<p:dialog widgetVar="dlgDelete" header="Desea eliminar la noticia #{newsBean.selectedNew.id}?">
<p:panel style="text-align: center">
<p:commandButton value="Si" update="newsTable" action="#{newsBean.removeNew}" oncomplete="dlgDelete.hide()" />
<p:commandButton value="No" onclick="dlgDelete.hide()" type="button" />
</p:panel>
</p:dialog>
<p:dialog header="Editar Noticia" widgetVar="editNewDialog" resizable="false"
showEffect="explode" hideEffect="explode" onHide="">
<p:ajax event="close" listener="#{fileUploadBean.deleteFileFromTemp}" update="messages"/>
<p:ajax event="close" listener="#{newsBean.deleteImageFromTemp}" update="messages"/>
<h:panelGrid id="display" columns="2" cellpadding="4">
<f:facet name="header">
<p>Noticia #{newsBean.selectedNew.id}</p>
<p>
<p:commandLink id="editImage">
<p:graphicImage id="imageNew" value="/temp/#{newsBean.selectedNew.img}" />
</p:commandLink>
<p:overlayPanel id="editImagePanel" for="editImage" hideEffect="fade">
<table cellpadding="5px">
<tr>
<td>
<p:commandButton title="Eliminar Imagen" update="imageNew" actionListener="#{newsBean.removeImage}" icon="ui-icon-trash"/>
</td>
<td>
<p:fileUpload
fileUploadListener="#{fileUploadBean.handleFileUpload}"
mode="advanced"
sizeLimit="1000000"
allowTypes="/(\.|\/)(gif|jpe?g|png)$/"
cancelLabel="Eliminar"
uploadLabel="Subir"
label="Buscar..."
dragDropSupport="false"
oncomplete="callChangeImage();"
onstart="callDeleteImageFromTemp();"
auto="true">
</p:fileUpload>
<p:commandLink id="hiddenLink" action="#{newsBean.changeImage(fileUploadBean.uploadedFile.fileName)}" style="display:none" update="imageNew"/>
<p:commandLink id="hiddenLink2" action="#{newsBean.deleteImageFromTemp}" style="display:none"/>
</td>
</tr>
</table>
</p:overlayPanel>
</p>
</f:facet>
<h:panelGrid id="display2" columns="2" cellpadding="4">
<h:outputText value="Titulo:" />
<p:inputTextarea rows="1" cols="60" value="#{newsBean.selectedNew.title}" id="title"/>
<h:outputText value="Descripcion:" />
<p:inputTextarea rows="6" cols="60" value="#{newsBean.selectedNew.description}" id="description"/>
<h:outputText value="Enlace:" />
<p:inputTextarea rows="1" cols="60" value="#{newsBean.selectedNew.link}" id="link"/>
</h:panelGrid>
<f:facet name="footer">
<p:commandButton value="Guardar" update="newsTable" actionListener="#{newsBean.saveNewEdit}" oncomplete="newDialog.hide()">
<p:ajax listener="#{fileUploadBean.writeUploadedFile('/images/news/', newsBean.selectedNew.id)}" update="messages"/>
</p:commandButton>
</f:facet>
</h:panelGrid>
</p:dialog>
</ui:define>
</ui:composition>
</h:body>
</html>
And my backend bean:
package Beans;
import helpers.Global;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
import javax.faces.context.FacesContext;
import org.apache.commons.io.FilenameUtils;
import org.primefaces.event.FileUploadEvent;
import org.primefaces.model.UploadedFile;
@ManagedBean
@SessionScoped
public class FileUploadBean {
private UploadedFile uploadedFile;
public FileUploadBean() {
}
public UploadedFile getUploadedFile() {
return uploadedFile;
}
public void setUploadedFile(UploadedFile uploadedFile) {
this.uploadedFile = uploadedFile;
}
public void writeUploadedFile(String path, String fileName){
try
{
if (this.uploadedFile != null)
{
String fileExtension = FilenameUtils.getExtension(this.uploadedFile.getFileName());
path += fileName + "." + fileExtension;
File file = new File(path);
if (file.exists()){
file.delete();
}
file.createNewFile();
InputStream is = uploadedFile.getInputstream();
OutputStream out = new FileOutputStream(file);
byte buf[] = new byte[1024];
int len;
while ((len = is.read(buf)) > 0){
out.write(buf, 0, len);
}
is.close();
out.close();
}else{
}
}catch (Exception ex){
Global.sendErrorsResponseMessage(ex.getMessage());
}
}
public void deleteUploadedFile(String path) {
if (this.uploadedFile != null)
{
path += uploadedFile.getFileName();
File file = new File(path);
if (file.exists()){
file.delete();
}
}
}
public void handleFileUpload(FileUploadEvent event) {
deleteFileFromTemp();
this.uploadedFile = event.getFile();
if (this.uploadedFile == null){
Global.sendErrorsResponseMessage("No se puedo cargar el archivo");
return;
}
try {
saveFileToTemp();
FacesMessage msg = new FacesMessage("Archivo cargado con exito", event.getFile().getFileName());
FacesContext.getCurrentInstance().addMessage(null, msg);
} catch (Exception ex) {
Global.sendErrorsResponseMessage(ex.getMessage());
}
}
public void saveFileToTemp(){
String path = FacesContext.getCurrentInstance().getExternalContext().getRealPath("/");
path = path + "temp" + Global.fileSeparator;
String fileName = FilenameUtils.removeExtension(this.uploadedFile.getFileName());
writeUploadedFile(path, fileName);
}
public void deleteFileFromTemp(){
if (this.uploadedFile != null){
String path = FacesContext.getCurrentInstance().getExternalContext().getRealPath("/");
String imageFileName = this.uploadedFile.getFileName();
path = path + "temp" + Global.fileSeparator + uploadedFile.getFileName();
File f = new File(path);
f.delete();
}
}
}
If this page is executed and you try to upload a file, the javascript "alerts" that are in the function "beforeUpload" and "afterUpload" are shown 4 times.
This is causing me a flashing in the image that is updated with the file upload.
I would appriciate any help as I'm kind of stucked with this.
Thanks for your help!
A little bit of background:
The purpose of this page is to add News (for a personalized news reader). In this page there's a table containing the News and each time a New row is selected a dialog appears to edit the New.
In that dialog, you have the image of the New and other stuff.
The objective was that when clicking the image in the editor, an overlay panel apperas with the options of uploading a new image or deleting the current image.
The commandButton with title "Eliminar Imagen" deletes the image of the New. The fileUpload uploads a new image for the New. So both of them should be updating the image of the New in the front end editor dialog.