frIT
frIT

Reputation: 3285

Client-side validation on <h:inputFile>

My JSF view uploads a file using plain <h:inputFile>. It has an AJAX action to start uploading as soon as a file is chosen (onchange event). I would like to do some basic validation on the file, using the HTML5 DOM File API and Javascript, on the client side to stop uploading in certain cases.

(Yes, I do understand that Javascript with this check can be circumvented, this is just a "bandwidth and time saving check" for normal users that accidentally choose the wrong file - there will still be server-side validations. And I also understand that the File API may not yet be available on all (older) browsers.)

Simplified JSF file:

<html
    xmlns="http://www.w3.org/1999/xhtml"
    xmlns:h="http://java.sun.com/jsf/html"
    xmlns:f="http://java.sun.com/jsf/core"
>
<h:head>
    <h:outputScript target="body">
//<![CDATA[
function doUpload(data, event) {
    if ("event" == data.type) {
        switch (data.status) {
            case "begin":
                // validate file size
                if (data.source.files[0].size > 20971520) { //20MiB
                    alert('ERROR: File too big!');
                    event.preventDefault();
                    return false;
                }
                // TODO show throbber
                break;

            case "complete":
                // TODO hide throbber
                break;

            case "success":
                break;
        }
    }
}
//]]>
    </h:outputScript>
</h:head>
<h:body>
    <h:form id="testuploadform" enctype="multipart/form-data">
        <h:inputFile id="uploadFile" name="uploadFile" value="#{testBean.uploadFile}">
            <!--  TODO validator/s for server-side validation -->
            <f:ajax event="change" listener="#{testBean.ajaxLst_autoUpload}"
                    onevent="function(data){ doUpload(data,event); }"
            />
        </h:inputFile>
    </h:form>
</h:body>
</html>

It seems that despite using the event.preventDefault() call, the event is still handled further: the file is uploaded and my listener function TestBean.ajaxLst_autoUpload() is able to obtain it and do work on it.

Is what I am trying to do even possible? And how do I go about it?

====

I guess a different approach would be to use the XMLHttpRequest.open() process to issue a request from AJAX (only once validation succeeds), I'm however unsure how one would do a "valid" POST request to JSF - I´ve only seen examples to PHP and Java Servlets. I'm not primarily keen to write an upload Servlet (although it can be done if needed and examples can be googled), and I don't know JSF under the hood too well to know how that would correspond with a Servlet. But any pointers in this regard would also be appreciated.

Upvotes: 2

Views: 1350

Answers (1)

BalusC
BalusC

Reputation: 1108782

Handling in <f:ajax onevent> is too late. Use the input component's onchange attribute instead. Basically:

<h:inputFile ... onchange="return validate(this)">

Upvotes: 4

Related Questions