1

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.

martin
  • 64
  • 1
  • 7
  • Please take some time to minimize the code and to remove all the irrelevant pieces that clutter the example. – siebz0r Sep 11 '12 at 05:14
  • most possibly you submit the page several times by one click. i think one comes from actionListener attribute of fileUpload component and other comes from the action of the commandButton. try to remove one of them. if it is not so, please explain what your actions do. – erencan Sep 11 '12 at 06:59
  • Hi! thanks for your answers. Im updating the post with some more explanation. I can't reduce the code because if so, nothing would be understandable. – martin Sep 11 '12 at 17:18

1 Answers1

-2

The action listener is invoked during the JSF lifecycle multiple times in the following Phases:

Apply request values phase; **process events**

Process validations phase; **process events**

Update model values phase; **process events**

Invoke application phase; **process events**
AVA
  • 1