p:fileUpload - 在上传之前验证表单

时间:2017-11-23 16:51:36

标签: jsf primefaces

我希望能够在我的表单上触发验证,然后在单击Primefaces中fileUpload控件的“选择”按钮时,允许选择要上传的文件。这可能吗?目前,用户可以单击“选择”和“上传”而不进行验证。这样可以防止我的文档保存但正在创建附件。 我知道我可以隐藏fileUpload控件,直到表单成功验证并保存,但是如果可能的话,我更愿意在单击“选择”按钮时调用验证。 我在onStart中尝试过remoteCommand调用,但似乎无法获得强制验证的任何内容。

1 个答案:

答案 0 :(得分:1)

p:fileUpload通过组合Java脚本和p:remoteCommand单击选择按钮时,可以触发表单验证。

基本概念

  • 拦截选择按钮点击事件,防止默认结果(打开文件选择器对话框)并改为运行p:remoteCommand
  • p:remoteCommand完成时,如果验证正常,请不要再阻止选择按钮点击,直到表单输入元素上的某些数据再次更改为止。

概念示例代码证明

在页面中添加 Java脚本

    <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>

并添加 p:remoteCommand

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

此处还有用于快速测试的xhtml页面

        <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>