ADF 11g – Validation of Uploaded Files with the inputFile component

 

Today we had a little issue with the inputFile component in ADF 11g, especially with its behavior after failed validation. Our situation: the inputFile component has autoSubmit set to true – so immediately after selecting a file in the browser dialog is the upload started in an asynchronous request. Validation is performed, either from validators or in a valueChangeListener (because I was too lazy to look up the syntax for a validator).

The behavior of the inputFile component is such that after the initial upload, the name of the uploaded file is shown as a read only value and the browse button is replaced by an update button: we can change the file, but not perform the initial upload anymore. When the user presses the update button, a small pop up appears in which we can browse for a file, click on the OK button to have it uploaded or click on Cancel to have the update aborted.

Unfortunately, when the file that was initially uploaded has failed validation, the OK button in this popup does not allow us to actually upload the newly selected file. The page continues to display the uploaded, invalid file and the update of that file to resolve the validation errors can not be performed.

We solved this issue

using the resetValue() method on the RichInputFile component: when we found that the uploaded file did not meet the validation rules, we add the FacesMessage to indicate the error, set the component to be invalid and we reset its value. Now the component is not changed to the readonly file name with update button, but instead continues to dispay as an input field with a browse button.

We feel this approach is justified as after uploading a file that does not pass validation, there is nothing the user can do to overcome that failure.

The code of the page and the bean

The page with the inputFile component:

    <af:document id="d1">
      <af:form id="f1" usesUpload="true">
        <af:panelHeader text="File Uploader" id="ph1">
          <af:inputText label="Value (String)" id="it1"
                        value="#{fileBean.someStringValue}"/>
<strong>          &lt;af:inputFile label=&quot;File to upload&quot; id=&quot;if1&quot; autoSubmit=&quot;true&quot;                          valueChangeListener=&quot;#{fileBean.fileUpdate}&quot;  <br />                        value=&quot;#{fileBean.file}&quot; partialTriggers=&quot;if1&quot;  /&gt;<br /></strong>        &lt;/af:panelHeader&gt;
        &lt;af:commandButton text=&quot;Save&quot; id=&quot;cb1&quot;/&gt;
      &lt;/af:form&gt;
    &lt;/af:document&gt;

The managed bean that holds the values and performs validation:

public class FileBean {

    private String       someStringValue;
    private UploadedFile file;
    private UIComponent inputFile;


    public void setFile(UploadedFile file) {
        this.file = file;
    }

    public UploadedFile getFile() {
        return file;
    }

    public void setInputFile(UIComponent inputFile) {
        this.inputFile = inputFile;
    }

    public UIComponent getInputFile() {
        return inputFile;
    }

    public void setSomeStringValue(String someStringValue) {
        this.someStringValue = someStringValue;
    }

    public String getSomeStringValue() {
        return someStringValue;
    }

    public void fileUpdate(ValueChangeEvent valueChangeEvent) {
        RichInputFile inputFileComponent = (RichInputFile)valueChangeEvent.getComponent();
        UploadedFile newFile = (UploadedFile)valueChangeEvent.getNewValue();
        if (newFile.getFilename().endsWith(&quot;gif&quot;)) {
<strong>          FacesContext.getCurrentInstance().addMessage( inputFileComponent.getClientId(FacesContext.getCurrentInstance())<br />                                                      , new FacesMessage(FacesMessage.SEVERITY_ERROR<br />                                                                         , &quot;GIF files are not allowed&quot;<br />                                                                         , &quot;This file (&quot;+ newFile.getFilename()+&quot;) is not allowed; the extension gif is not allowed.&quot;<br />                                                                         )<br />                                                      );<br />          inputFileComponent.resetValue();<br />          inputFileComponent.setValid(false);<br /></strong>        }
    }
}

Resources

JDeveloper 11g project with the sources: InputFileValidation.zip.

  1. Aoa, Dear
    it is very nice tutorial helped me a lot. Now i want to upload a image file in a blob column but i don’t know how to do it. Please help me if you can
    Thanks  in advance

  2. Hi,
    This is an excelent tutorial… congrats….
    Well, currently im doig a little experiment with ADF (im pretty new with ADF)… and i am having some problems, and i hope if you can help me.
    I downloaded this example, and i wan’t to do some modifications… but the app just don’t word :P
    What im trying to do is that when you select a file, and the extension is a valid… it appear a new inputfile behind the one with the file “loaded” ….
    Right now i have a button with “add another file” … but isn’t working right… cause when i click the button to add another inputfile the previous one just .. kind of “reset” … i lost the file i already load…
    in the button action i have that:

    public void newInputFile() {
    String uniqueid = “if” + contadorId;
    RichInputFile inputFile = new RichInputFile();
    inputFile.setId(uniqueid);
    inputFile.setLabel(contadorId + “.- Archivo: “);
    inputFile.setInlineStyle(“border-style:none;”);
    panelForm.getChildren().add(inputFile);
    }
    i already bind the panel form where i want to add the new input file…
    right now i can add new’s inputs files loosing the loaded previous one… but the original idea was that when i load a file and if the extension of the file is right… automatic create a new inputfile (but i spend several days working on that and nothing)
    other issue i have is when i trying to add the value change listener at the new inputfile: inputFile.setValueChangeListener(); … i don’t now how to bind the fileUpdate method…
    Well i hope you can help me… thanks very much from Mexico :-]