NeilC
NeilC

Reputation: 13

p:fileUpload - Validate form prior to upload

I would like to be able to trigger validation on my form prior to being allowed to select the files for upload when clicking on the "Choose" button of the fileUpload control in Primefaces. Is this possible? At present the user can click on "Choose" and "Upload" without validation kicking in. This is preventing my document from saving but the attachments are being created. I know I could hide the fileUpload control until the form is successfully validated and saved but I would prefer to invoke validation when you click the "Choose" button if possible. I've tried remoteCommand calls in the onStart but can't seem to get anything to force validation to occur.

Upvotes: 1

Views: 2407

Answers (1)

Dusan Kovacevic
Dusan Kovacevic

Reputation: 1437

It is possible to trigger form validation when p:fileUpload Choose button is clicked by combining Java Script and p:remoteCommand.

BASIC CONCEPT

  • intercept Choose button click event, prevent default outcome (opening of file chooser dialog) and run p:remoteCommand instead,
  • when p:remoteCommand completes, and if validation is OK, do not prevent Choose button clicks any more until some data on form input elements is changed again.

PROOF OF CONCEPT EXAMPLE CODE

Add this Java script in your page

    <script>
            var triggerValidation;
            window.onload = function () {
                //initially (after page is loaded) trigger validation on Choose btn click
                triggerValidation = true;
                //define button click listener
                registerChooseBtnClick();
            };

            function registerChooseBtnClick() {
                //var chooseBtn = document.getElementsByClassName("ui-fileupload-choose")[0];
                // or if you define p:upload widgetVar you can use PF function            
                var chooseBtn = PF('fileUploadWidget').chooseButton[0];
                chooseBtn.addEventListener('click', fnRef, false);
            }

            var fnRef = function (event) {
                console.log("Button clicked");
                if (triggerValidation) {
                    //prevent file browser to open
                    event.preventDefault();
                    //trigger validation via p:remoteCommand;
                    submitSelection();
                } else {
                    //File browser will be opened at this point
                }
            };

            function checkIfValidationFailed(xhr, status, args) {
                if (args) {
                    if (args.validationFailed) {
                        console.log("Validation failed");
                        triggerValidation = true;
                    } else {
                        triggerValidation = false;
                    }
                }
            }

            //call each time when form input elements (inputText, ...) change value
            function forceValidation(){
                triggerValidation = true;
            }

        </script>

and add p:remoteCommand

            <p:remoteCommand
                name="submitSelection" process="@form" 
                oncomplete="checkIfValidationFailed(xhr, status, args)" resetValues="true"/>

Also here is xhtml page for quick testing

        <h:form id="form">
            <p:messages autoUpdate="true"/>
            <p:panelGrid columns="1">
                <!--size is integer variable-->
                <p:inputText id="size" maxlength="3"
                             value="#{yourBean.size}" 
                             required="true" requiredMessage="Size is missing"
                             onchange="forceValidation();"/>

                <p:fileUpload
                    id="upload"
                    widgetVar="fileUploadWidget"
                    fileUploadListener="#{yourBean.onUpload}"
                    multiple="true"
                    allowTypes="/(\.|\/)(jpg|png)$/" />
            </p:panelGrid>

            <p:remoteCommand
                name="submitSelection" process="@form" 
                oncomplete="checkIfValidationFailed(xhr, status, args)" resetValues="true"/>
            <p:commandButton
                id="submitBtn" value="Sumbit" process="@form"
                actionListener="#{yourBean.onSubmit()}"/>
        </h:form>

Upvotes: 1

Related Questions