Search code examples
jsffile-uploadjsf-2richfaces

How limit RichFaces 4 rich:fileUpload to single file upload?


I'm using the <rich:fileUpload /> from RichFaces4 as you can see here. But as you can see, there user can select a lots of picture but I want him could select just one picture.

And how do I call a method in my managed bean (which send the image to my Amazon S3 bucket) after the upload has been completed ?

EDIT:

<ui:composition>
<h:outputStylesheet>
    .top {
        vertical-align: top;
    }

    .info {
        height: 202px;
        overflow: auto;
    }

    .rf-fu-lst {
        height: 60px;
    }

    .rf-fu-itm {
        border: 0;
    }
</h:outputStylesheet>
<h:outputScript target="head">
jQuery.extend(RichFaces.ui.FileUpload.prototype, {
    __updateButtons: function() {
        if (!this.loadableItem && this.list.children(".rf-fu-itm").size()) {
            if (this.items.length) {
                this.uploadButton.css("display", "inline-block");
                this.addButton.hide();
            } else {
                this.uploadButton.hide();
                this.addButton.css("display", "inline-block");
            }
        } else {
            this.uploadButton.hide();
            this.addButton.css("display", "inline-block");
        }
    }
});
</h:outputScript> 

    <h:form id="form_user_upload_picture" >
        <h:panelGrid columns="2" columnClasses="top, top">
            <rich:fileUpload  
                id="upload" 
                fileUploadListener="#{user_file_upload.listener}"
                acceptedTypes="jpg, gif, png, bmp" 
                addLabel="Adicionar" 
                clearAllLabel="Limpar todas" 
                clearLabel="limpar" 
                deleteLabel="apagar" 
                doneLabel="upload realizado" 
                sizeExceededLabel="arquivo muito grande, tente um arquivo de tamanho menor" 
                serverErrorLabel="ocorreu um erro em nosso servidor, tente novamente por favor"
                uploadLabel="Enviar">

                <a4j:ajax event="uploadcomplete" execute="@none" render="picture" />
            </rich:fileUpload>
        </h:panelGrid>

    </h:form>
</ui:composition>

Solution

  • This was used to be supported in RF 3.3. But to save time for RF 4.0 migration, among others the <rich:fileUpload> got much less attention than it deserves. There are currently a lot of open tickets to improve it.

    Until they improves it, your current best bet is to bring in some custom jQuery/JS and CSS to achieve the functional requirement of selecting and uploading only one file.

    This script prevents the enduser from uploading multiple files by hiding the add button when there's already a file selected:

    jQuery.extend(RichFaces.ui.FileUpload.prototype, {
        __updateButtons: function() {
            if (!this.loadableItem && this.list.children(".rf-fu-itm").size()) {
                if (this.items.length) {
                    this.uploadButton.css("display", "inline-block");
                    this.addButton.hide();
                } else {
                    this.uploadButton.hide();
                    this.addButton.css("display", "inline-block");
                }
            } else {
                this.uploadButton.hide();
                this.addButton.css("display", "inline-block");
            }
        }
    });
    

    Make sure that the above JS is loaded after the RF default scripts (which includes jQuery already). You could do that by a <h:outputScript> in the body which you can if necessary set with target="head".

    This CSS limits the height of the file list and removes the bottom border of the single item:

    .rf-fu-lst {
        height: 60px;
    }
    .rf-fu-itm {
        border: 0;
    }
    

    Make sure that the above CSS is loaded after the RF default styles. You could do that by a <h:outputStylesheet> in the body (so don't put in head).


    And how do I call a method in my managed bean (which send the image to my Amazon S3 bucket) after the upload has been completed ?

    Just do the job in the listener method which is attached to fileUploadListener attribute.

    <rich:fileUpload fileUploadListener="#{bean.upload}">