自定义 HTML5 表单验证错误仅在第一次尝试后发生

2024-04-11

下面的代码允许我的客户创建具有不同类型字段的自定义表单,然后允许他们的客户填写该表单并将其提交到某处。基本上,Wordpress 的自定义表单生成器。

我已成功替换了自定义行为HTML5使用以下代码形成验证错误消息。但是,我为不同类型的表单字段设置的自定义消息仅在第二次尝试提交表单时出现。第一次按下提交按钮时,会显示默认消息。

如何才能让我定义的自定义消息也能在第一次使用?

抱歉代码很长,这是一个复杂的应用程序。在里面PHP部分,查看下面的Start Input Wrap我设置自定义错误消息的部分,如下所示:

onchange="setCustomValidity(\'\')" oninvalid="this.setCustomValidity(\''.$placeholder.' is required.\')"

PHP/HTML:

function sdForm($atts) {
    //Check for a form id variable in the shortcode and, if it's exists, put it into the $formID variable
    $shortcodeAtt = shortcode_atts( array(
        'id' => false,
        ), $atts );
    if ($shortcodeAtt != false) {
        $formID = $shortcodeAtt['id'];

        //Setup this form's settings and variables
        global $post;
        $post = get_post($formID);
        setup_postdata($post);

        //General Variables
        $formTitle = get_the_title();
        $formSlug = $post->post_name;

        //Form Submit Behavior
        $onSubmit = get_field('on_form_submit');
        if ($onSubmit == 'default') {
            //refresh page, display thank you
        } elseif ($onSubmit == 'message') {
            //refresh page, display custom message
            $message = get_field('custom_submission_message');
        } elseif ($onSubmit == 'url') {
            //send user to this page
            $url = get_field('submission_redirect');
        }

        //Form Submit To
        $actionUrl = get_field('form_action_link');

        //Set value of submit button
        if (get_field('submit_value')) {
            $submitValue = get_field('submit_value');
        } else {
            $submitValue = 'Submit';
        }

        //Set ID for form
        if (get_field('form_id')) {
            $formHtmlId = get_field('form_id');
        } else {
            $formHtmlId = $formSlug;
        }

        //Set Classes for form
        if (get_field('form_classes')) {
            $formClasses = get_field('form_classes');
        } else {
            $formClasses = '';
        }

        //Set any messages to display
        $messages = '';
        $confirmMessage = get_field('custom_submission_message');
        if ($_GET['confirm-message']) {
            $messages .= $confirmMessage.'<br />';
        } elseif ($_GET['confirm-submit']) {
            $messages .= 'Thanks for your submission!';
        }

        //Start the HTML output
        $output = '';
        //Do some clearing, just in case
        $output .= '<div style="clear:both;"></div>';
        $output .= '<div class="sdFormWrapper">';
        $output .= '<div class="sdFormMessages">';
        $output .= $messages;
        $output .= '</div>';
        $output .= '<form name="'.$formSlug.'" id="'.$formHtmlId.'" class="'.$formClasses.' sd_form" method="post" ';
        if (isset($actionUrl)) {
            $output .= 'action="'.$actionUrl.'" ';
        }
        $output .= '>';

        //We add a hidden field to identify which form is being processed after submit
        $output .= '<input type="hidden" name="formID" value="'.$formID.'" />';

        //This loops through each added field and displays each one
        if (have_rows('input_type')) {
            while (have_rows('input_type')) { the_row();

            //We're putting a uniform wrap around each input element for styling
            if (get_sub_field('fill_row') == true) {
                $fullWidth = 'fullWidth';
            } else {
                $fullWidth = '';
            }
            if (get_row_layout() == 'section_header') {
                $output .= '<div class="sectionHeader">';
                $output .= get_sub_field('header_text');
                $output .= '</div>';
            } else {



            //We turn the field label into a slug with no spaces or special characters
            $fieldSlug = sanitize_title(get_sub_field('label'));

            //Check if this field is required
            if (get_sub_field('required') == true) {
                    $required = 'required';
            } else {
                    $required = '';
            }
            //Check for custom name
            if (get_sub_field('input_name')) {
                $name = get_sub_field('input_name');
            } else {
                $name = $fieldSlug;
            }
            //Check for custom html id
            if (get_sub_field('input_id')) {
                $htmlId = get_sub_field('input_id');
            } else {
                $htmlId = $name;
            }
            //Check for custom html classes
            if (get_sub_field('input_class')) {
                $htmlClass = get_sub_field('input_class').' sdForm-input';
            } else {
                $htmlClass = 'sdForm-input';
            }
            //Check for icons
            if (get_sub_field('icon')) {
                    $icon = get_sub_field('icon');
                } else {
                    $icon = '';
                }
            //Generate Placeholder  (this is the field label)
            $placeholder = get_sub_field('label');

            //Start input wrap
            $output .= '<div title="'.$placeholder.'" class="sdForm-inputWrap '.$fullWidth.'">';

            //Error message for field
            //$output .= '<div class="inputError">'.$placeholder.' is required!</div>'; 
                $output .= $icon;
                if (get_row_layout() == 'text') {
                    $output .= '<input type="text" name="'.$name.'" id="'.$htmlId.'" class="'.$htmlClass.'" placeholder="'.$placeholder.'" title="'.$placeholder.'" '.$required.' onchange="setCustomValidity(\'\')" oninvalid="this.setCustomValidity(\''.$placeholder.' is required.\')"  />';
                } elseif (get_row_layout() == 'textBox') {
                    $output .= '<textarea rows="4" id="'.$htmlId.'" class="'.$htmlClass.'" placeholder="'.$placeholder.'" title="'.$placeholder.'" '.$required.' onchange="setCustomValidity(\'\')" oninvalid="this.setCustomValidity(\''.$placeholder.' is required.\')"></textarea>';
                } elseif (get_row_layout() == 'email') {
                    $output .= '<input type="email" name="'.$name.'" id="'.$htmlId.'" class="'.$htmlClass.'" placeholder="'.$placeholder.'" title="'.$placeholder.'" '.$required.' onchange="setCustomValidity(\'\')" oninvalid="this.setCustomValidity(\''.$placeholder.' is required and must be valid.\')"/>';
                } elseif (get_row_layout() == 'phone') {
                    $output .= '<input type="tel" name="'.$name.'" id="'.$htmlId.'" class="'.$htmlClass.'" placeholder="'.$placeholder.'" title="'.$placeholder.'" '.$required.' onchange="setCustomValidity(\'\')" oninvalid="this.setCustomValidity(\''.$placeholder.' is required.\')"/>';
                } elseif (get_row_layout() == 'url') {
                    $output .= '<input type="url" name="'.$name.'" id="'.$htmlId.'" class="'.$htmlClass.'" placeholder="'.$placeholder.'" title="'.$placeholder.'" '.$required.' onchange="setCustomValidity(\'\')" oninvalid="this.setCustomValidity(\''.$placeholder.' is required.\')"/>';
                } elseif (get_row_layout() == 'checkboxes') {
                    if (have_rows('checkbox_selections')) {
                        if ($placeholder != '') {
                            $output .= '<label for="'.$htmlId.'">'.$placeholder.'</label><br />';
                        }
                        while(have_rows('checkbox_selections')) { the_row();
                            $selection = get_sub_field('checkbox_selection');
                            $output .= '<input type="checkbox" name="'.$name.'" value="'.$selection.'" id="'.$htmlId.'" class="'.$htmlClass.'" title="'.$placeholder.'" '.$required.' onchange="setCustomValidity(\'\')" oninvalid="this.setCustomValidity(\''.$placeholder.' is required.\')"/>';
                            $output .= '&nbsp;&nbsp;<label for="'.$htmlId.'">'.$selection.'</label><br />';
                        }
                    }
                } elseif (get_row_layout() == 'radios') {
                    if (have_rows('radio_selections')) {
                        if ($placeholder != '') {
                            $output .= '<label for="'.$htmlId.'">'.$placeholder.'</label><br />';
                        }
                        while(have_rows('radio_selections')) { the_row();
                            $selection = get_sub_field('radio_selection');
                            $output .= '<input type="radio" name="'.$name.'" value="'.$selection.'" id="'.$htmlId.'" class="'.$htmlClass.'" title="'.$placeholder.'" '.$required.' onchange="setCustomValidity(\'\')" oninvalid="this.setCustomValidity(\''.$placeholder.' is required.\')"/>';
                            $output .= '&nbsp;&nbsp;<label for="'.$htmlId.'">'.$selection.'</label><br />';
                        }
                    }
                } elseif (get_row_layout() == 'select') {
                    if (get_sub_field('show_label', true)) {
                        $output .= '<span class="dropdownLabel">'.$placeholder.': </span>';
                        $showLabel = 'showLabel';
                    } else {
                            $showLabel = '';
                    }
                    $optionSlug = sanitize_title($selection);
                    if (have_rows('dropdown_selections')) {

                        $output .= '<select name="'.$name.'" id="'.$htmlId.'" class="'.$htmlClass.' '.$showLabel.'" title="'.$placeholder.'" '.$required.' onchange="setCustomValidity(\'\')" oninvalid="this.setCustomValidity(\''.$placeholder.' is required.\')">';                  
                        $output .= '<option selected="select" disabled>';
                        if ($showLabel != 'showLabel') {
                            $output .= $placeholder;
                        }
                        $output .= '</option>';
                        while(have_rows('dropdown_selections')) { the_row();
                            $selection = get_sub_field('dropdown_selection');
                            $optionSlug = sanitize_title($selection);
                            $output .= '<option value="'.$optionSlug.'">'.$selection.'</option>';                           
                        }
                        $output .= '</select>';
                    }
                } 
            $output .= '<div style="clear:both;"></div>';
            $output .= '</div>'; //.sdForm-inputWrap
            } //end else (if not a message header)
            }//endwhile

        }

        $output .= '<input type="submit" value="'.$submitValue.'" />';

        $output .= '</form><div style="clear: both;"></div></div>';

        wp_reset_postdata();

    } else { //There is no ID set, so we can't show any form
        //ERROR!! No form ID specified
    }
    echo $output;
}

add_shortcode('sdForm', 'sdForm');

JS:

 (function($) {
     $(document).ready(function() {
         function sd_replaceValidationUI(form) {
             // Suppress the default bubbles
             form.addEventListener("invalid", function(event) {
                 event.preventDefault();
             }, true);

             // Support Safari, iOS Safari, and the Android browser—each of which do not prevent
             // form submissions by default
             form.addEventListener("submit", function(event) {
                 if (!this.checkValidity()) {
                     event.preventDefault();
                 }
             });

             var submitButton = form.querySelector("button:not([type=button]), input[type=submit]");
             submitButton.addEventListener("click", function(event) {
                 var invalidFields = form.querySelectorAll(":invalid"),
                     errorMessages = form.querySelectorAll(".error-message"),
                     parent;

                 // Remove any existing messages
                 for (var i = 0; i < errorMessages.length; i++) {
                     errorMessages[i].parentNode.removeChild(errorMessages[i]);
                 }

                 for (var i = 0; i < invalidFields.length; i++) {
                     parent = invalidFields[i].parentNode;
                     parent.insertAdjacentHTML("beforeend", "<div class='error-message'>" +
                         invalidFields[i].validationMessage +
                         "</div>");
                 }

                 // If there are errors, give focus to the first invalid field
                 if (invalidFields.length > 0) {
                     invalidFields[0].focus();
                 }
             });
         }

         // Replace the validation UI for all forms
         var forms = document.querySelectorAll("form");
         for (var i = 0; i < forms.length; i++) {
             sd_replaceValidationUI(forms[i]);
         }


         //Changes the text of the dropdown to #666 when a selection is made
         $('.sdForm-inputWrap select').change(function() {
             $(this).css('color', '#666');
         });

     })
 })(jQuery);

我认为你的问题是你正在设置自定义有效性oninvalid。这适用于默认 UI,但不适用于您想要自定义它的情况。

我尝试重新创建你的代码。第一次运行时invalidFields循环正在获取默认的无效错误消息。在此之后setCustomValidity然后调用,因此您在第二次运行时会收到自定义错误消息。

要解决此问题,您必须循环遍历要设置自定义有效性的所有字段并调用setCustomValidity在提交表格之前。

一种方法是利用数据属性HTML代码。为每个字段添加如下属性:

<input type="text" data-ErrorMessage="Your Custom Error Message" />

然后将其添加到现有的js中:

for (var i=0; i<fields.length; i++){
    var message = $(fields[i]).attr("data-ErrorMessage");
    $(fields[i]).get(0).setCustomValidity(message);
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

自定义 HTML5 表单验证错误仅在第一次尝试后发生 的相关文章

  • 混合应用程序开发(PhoneGap、Cordova、Ionic)

    我试图了解一切是如何运作的 但对此主题有一些疑问 我将解释我如何理解这些东西 首先让我们从Cordova这是翻译平台JS CSS HTML文件到本机应用程序中 但这并不完全是事实 实际上 它只是将所有 html css 文件放入 asset
  • 如何使用 jsPDF 和 HTML2Canvas 从网站获取多页 pdf?

    我有一个使用 HTML2Canvas 来截取屏幕截图的脚本div在页面中 然后使用 jsPDF 将其转换为 pdf 问题是生成的 pdf 只有一页 而屏幕截图在某些情况下需要不止一页 例如 屏幕截图大于 8 5x11 宽度很好 但我需要它来
  • 您可以强制 HTML 表单对相对 URL 使用 HTTPS 吗?

    我有一个网站 其中每个页面都通过 HTTPS 提供服务 在其中一个页面上 我有一个表单 其操作属性设置为相对 URL 包含表单的页面只能通过 HTTPS 访问 表单发布到的页面只能通过 HTTPS 访问 但在 IE 中 我收到一条安全警告
  • 使用 javascript/jQuery 更改类的背景颜色属性

    这似乎是一个简单的问题 但没有任何解决办法 我正在尝试使用 javascript jQuery 动态更改某些文本的背景颜色 从白色或粉色到绿色 但由于某种原因它不起作用 文本使用名为 novice 的 CSS 类进行样式设置 这是CSS 这
  • 从 html 链接在移动设备上打开应用程序

    我有一个包含我的社交媒体帐户的 html 页面 我希望当我单击这些链接时可以转到我在这些社交媒体应用程序上的个人资料 例如 Skype a href My Skype a 当我在移动设备上点击此链接时 它会打开 Skype 并转到我的帐户
  • 插入标准模式文档中的动态 iframe 默认为怪异模式

    我有一份当前正在返回的父文档CSS1Compat from document compatMode 当我使用 jQuery 添加一个空白 iframe 时 如下所示 body append 并检查新 iframe 的 compatMode
  • jQuery触发新添加的html代码

    示例我有 2 个 html 输入 div class wrap div
  • 如何为 Safari 浏览器设置媒体查询

    media only screen and min width 480px and max width 767px 这是我的媒体查询如何修复它 如何设置 safari 网络浏览器 媒体查询不是为了浏览器检测而进行的 使用 javascrip
  • Spring MVC 3 中的表单提交 - 说明

    我在理解 Spring 3 MVC 中的表单提交如何工作时遇到问题 我想做的是创建一个控制器 它将获取用户的名字并将其显示给他 不知怎的 我已经做到了 但我不太明白它是如何工作的 所以 我有一个看起来像这样的表格
  • Javascript:确认、确定、取消按钮上的自定义文本

    我有一个验证 我想显示 继续 和 返回 而不是 确定 和 取消 但我无法找到准确的解决方案 任何人都可以帮助我
  • 如何在 CQRS 中处理基于集合的一致性验证?

    我有一个相当简单的域模型 涉及一系列Facility聚合根 鉴于我使用 CQRS 和事件总线来处理从域引发的事件 您如何处理集合的验证 例如 假设我有以下需求 Facility必须有一个唯一的名称 由于我在查询端使用最终一致的数据库 因此在
  • 使用 JavaScript 或 jQuery 设置文本框的最大长度

    我想用 JavaScript 或 jQuery 更改文本框的最大长度 我尝试了以下方法 但似乎没有帮助 var a document getElementsByTagName input for var i 0 i
  • 在 Angular 4 Reactive Forms 中提交时显示验证消息

    我正在使用 Angular 4 反应式表单 我想在用户单击 提交 创建帐户 按钮时显示验证错误消息 这是我正在使用的 HTML 和打字稿代码
  • Doctype的实际使用

    虽然我在 w3 org 上浏览了大量有关 Doctype 的信息并了解不同类型的 doctype 过渡型 严格型 框架集 我还是不太清楚在页面上使用Doctype的实际用途是什么 I mean 是为了阻止开发商 在代码中使用某些标签 例如
  • 将类添加到一组

    我有一群 ul 是动态创建的 我需要在最后添加一个类 li 每一个 I have ul li last each function this addClass last 但这仅仅增加了一个class last 到最后 ul 不在所有的 ul
  • 为什么 jQuery 在其构造函数实现中要这样做?

    如果我们查看最新的 jQuery 源代码http code jquery com jquery latest js http code jquery com jquery latest js我们看到以下内容 var jQuery funct
  • HTML 电子邮件:表格还是 div?

    html 电子邮件通讯的 HTML CSS 是否需要采用表格格式 或者我可以使用 DIV 来保证它能够在跨电子邮件客户端上良好地显示吗 我下载了许多模板来看看它们是如何完成的 并以此为基础构建我自己的模板 它们似乎都使用表格 非常感谢任何见
  • 想要在 highcharts/highstock 中用鼠标滚轮移动 y 轴滚动条

    参考我想用鼠标滚轮移动 y 轴滚动条的问题 有什么办法可以做到吗 yAxis scrollbar enabled true showFull false 更新代码 下面是我更新的代码 var chart1 new Highcharts Ch
  • jQuery ajax 调用在 Mac Safari 和 Chrome 浏览器上返回空错误

    我几天来一直在寻找解决方案并尝试修复 但没有任何改变 老板使用的是 Mac 而我没有 所以我让他尝试重复修复并将输出转发给我 到目前为止还没有运气 因此 当前的设置是 我有一个包含用户名和密码输入的表单 该表单在经过验证后提交 验证是一个
  • 在 Bootstrap 导航栏后添加一些空间的最佳方法是什么?

    以下代码始终在页面顶部显示导航栏 我需要将第二个容器 内容 放置在导航栏的末尾而不是其下方 目前第二个容器位于导航栏下方 我可以在内容顶部添加一些空白 但我不确定这是一个好方法 知道如何解决吗 div class container div

随机推荐