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

Eck*_*ein 5 forms validation jquery html5

下面的代码允许我的客户创建一个包含不同类型字段的自定义表单,然后允许他们的客户填写该表单并在某处提交.基本上,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');
Run Code Online (Sandbox Code Playgroud)

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);
Run Code Online (Sandbox Code Playgroud)

Dig*_*ble 0

我认为你的问题是你正在设置自定义有效性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);
}
Run Code Online (Sandbox Code Playgroud)