【问题标题】:p:fileUpload - Validate form prior to uploadp:fileUpload - 在上传之前验证表单
【发布时间】:2017-11-23 16:51:36
【问题描述】:

单击 Primefaces 中 fileUpload 控件的“选择”按钮时,我希望能够在允许选择要上传的文件之前触发我的表单验证。这可能吗?目前,用户可以单击“选择”和“上传”而不进行验证。这会阻止我的文档保存,但正在创建附件。 我知道我可以隐藏 fileUpload 控件,直到成功验证并保存表单,但如果可能,我更愿意在单击“选择”按钮时调用验证。 我已经在 onStart 中尝试了 remoteCommand 调用,但似乎没有任何东西可以强制进行验证。

【问题讨论】:

  • 您可以在 bean 控制的“禁用”属性中使用布尔变量,并在验证后更新上传组件和此变量。
  • 您好豪尔赫,感谢您的回复。当用户单击“选择”时,我如何调用验证。我想这样做,因为它会在用户上传附件之前向用户提供有关所需内容的反馈。

标签: jsf primefaces


【解决方案1】:

结合Java Script和p:remoteCommand,点击p:fileUpload选择按钮时可以触发表单验证。

基本概念

  • 拦截选择按钮单击事件,阻止默认结果(打开文件选择器对话框)并改为运行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>

【讨论】:

  • 谢谢,很好的解决方案!我的文档有一个读取/编辑模式的小问题,它阻止 onLoad 事件注册触发器“选择”按钮(上传控件在读取模式下隐藏),但我确信我可以解决它。跨度>
  • 我很高兴它可能对你有用。在这种情况下,您可以在切换到编辑模式后注册触发器,并在切换到读取模式后使用 chooseBtn.removeEventListener 取消注册。
  • 另外,如果您最终发现此答案有用,请阅读What should I do when someone answers my question? :)
  • 只是另一件事......虽然'args'正在返回validationFailed,但它似乎没有突出显示我的必填字段,因此没有向用户表明表单失败。这是正确的吗?
  • 我认为您应该将 添加到每个字段以实现这一目标。您可以在PF showcase 中查看示例
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-01-03
  • 1970-01-01
  • 2018-06-18
  • 2016-12-30
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多