jQuery验证:无法在表单验证上切换下一个面板

时间:2017-01-21 10:05:17

标签: jquery jquery-validate

我已经在这个问题上苦苦挣扎了两天多了。

我正在尝试为我的WooCommerce结帐实现Bootstrap手风琴。我设法让基本的手风琴行为很好地运作。但是,由于我想为客户提供一种复杂的体验,我正在努力使这种结帐表格尽可能花哨(同时又方便用户使用)。首先,我必须使用jQuery来确保在离开页面后没有表单提交,通过localstorage保留每个字段的值。

然后,我停用了面板2和3.这个想法是让每个面板逐渐为客户所用。你可以在这里看到一个jsfiddle:https://jsfiddle.net/9vjcoLxh/6/

我还在表单中添加了jQuery Validation。另请注意,“登录/注册”面板仅在注销时显示。如果用户已登录,则不会显示。相反,如果用户已登录,则会自动切换下一个面板以允许更好的结帐流程。我想仅验证第二个面板,因为它包含实际的客户信息(姓名,电子邮件地址等)。验证将在按钮点击时启动,这是我的片段:

jQuery('#toggle-delivery').click( function() {       
  jQuery("#validate-info").validate({         
    rules: {
     phone_number: {
        required: true,
        digits: true,
        minlength: 9
     },
     email_address: {
        required: true,
        email: true
      },
      shipping_first_name: {
        required: true,
        minlength: 2
      },
      shipping_last_name: {
        required: true,
        minlength: 2
      }
    },
    onfocusout: function(e) {
            this.element(e);
    },
    messages: {
         phone_number: {
          required: "Please enter a valid UK phone number",
          digits: "Please enter a valid UK phone number.",
          minlength: "Please enter at least 9 characters"
         },
         email_address: {
            required: "We need your email address to contact you.",
            email: "Oops! This isn't a correct email format. Please check and try again."
         },
         shipping_first_name: {
          minlength: "Please enter at least 2 characters."
         },
         shipping_last_name: {
          minlength: "Please enter at least 2 characters."
         },
         shipping_address_1: {
          required: "Please enter a valid UK address.",
          minlength: "Please enter a valid UK address."
         }
    }
  }).form(); 
});

这很好用。但是,我更进一步,通过添加此代码段,阻止面板中的数据崩溃,下一个数据扩展,如果表单无效:

jQuery('#toggle-delivery').click(function(e){
    e.preventDefault();
    var sectionValid = true;
    var collapse = jQuery(this).closest('.panel-collapse.collapse');
    jQuery.each(collapse.find('input, select, textarea'), function(){
        if(!jQuery(this).valid()){
            sectionValid = false;
        }
    });
    if(sectionValid){
        collapse.collapse('toggle');
        collapse.parents('.panel').next().find('.panel-collapse.collapse').collapse('toggle');
    }
});

同样,它运作良好。但是,我注意到只有在用户登录时才能正常运行。如果没有,则表单仅在单击时验证,但活动面板未折叠+下一个未切换。这就好像最后一个片段不起作用 - 这非常奇怪,因为如果用户登录,它可以很好地工作。

我不是jQuery / JS精明,也不是WooCommerce专家,所以我不知道问题可能是什么。我尝试了很多解决方案,但无济于事。我激活了脚本调试,没有显示任何内容。 JS控制台中也没有错误。我在Chrome和Firefox上尝试了相同的结果。

我真的很感激对可能出现的问题的一些意见。

2 个答案:

答案 0 :(得分:0)

jQuery('#toggle-delivery').click( function() {       
    jQuery("#validate-info").validate({ ...

您绝对不应该在.validate()处理程序中使用click方法。 .validate()方法仅用于初始化表单上的插件,并且只在页面加载时调用一次。

一旦验证每个面板,默认情况下,jQuery Validate插件将忽略隐藏的任何内容。因此,只有外露的面板才会被验证,因此您不需要任何特殊的处理程序来检查每个输入。

答案 1 :(得分:0)

感谢@Sparky的回答。但是,没有任何字段被隐藏 - 它们对于登录和注销用户都是相同的。尽管如此,下一个面板的验证+切换仅适用于登录用户,因此我不得不放弃此方法并采用不同的路径。

我已将btn-disabled类添加到之前验证表单的按钮,以及data-toggle="collapse" data-parent="#checkout-accordion" href="#collapse-delivery"以使其切换到下一个面板。我已将以下CSS属性添加到btn-disabled类:

.btn-disabled {
pointer-events: none;
cursor: default;
color: #ececec;
background-color: #c4c4c4;
}

这使按钮无法点击,因此用户无法折叠当前面板并切换下一个按钮。这是我修改过的jQuery验证片段:

jQuery(document).ready(function() {
    jQuery('input').on('blur', function() {
        if (jQuery("#validate-info").validate().checkForm()) {
            jQuery('#toggle-delivery').removeClass("btn-disabled");  
        } else {
            jQuery('#toggle-delivery').addClass("btn-disabled");
        }
});
  jQuery("#validate-info").validate({         
    rules: {
     phone_number: {
        required: true,
        digits: true,
        minlength: 9
     },
     email_address: {
        required: true,
        email: true
      },
      shipping_first_name: {
        required: true,
        minlength: 2
      },
      shipping_last_name: {
        required: true,
        minlength: 2
      },
     billing_phone: {
        required: true,
        digits: true,
        minlength: 9
     },
     billing_email: {
        required: true,
        email: true
      },
      billing_first_name: {
        required: true,
        minlength: 2
      },
      billing_last_name: {
        required: true,
        minlength: 2
      }
    },
    onfocusout: function(e) {
            this.element(e);
    },
    onkeyup: false,
    messages: {
         phone_number: {
          required: "Please enter a valid UK phone number",
          digits: "Please enter a valid UK phone number.",
          minlength: "Please enter at least 9 characters"
         },
         email_address: {
            required: "We need your email address to contact you.",
            email: "Oops! This isn't a correct email format. Please check and try again."
         },
         shipping_first_name: {
          minlength: "Please enter at least 2 characters."
         },
         shipping_last_name: {
          minlength: "Please enter at least 2 characters."
         },
          billing_phone: {
          required: "Please enter a valid UK phone number",
          digits: "Please enter a valid UK phone number.",
          minlength: "Please enter at least 9 characters"
         },
         billing_email: {
            required: "We need your email address to contact you.",
            email: "Oops! This isn't a correct email format. Please check and try again."
         },
         billing_first_name: {
          minlength: "Please enter at least 2 characters."
         },
         billing_last_name: {
          minlength: "Please enter at least 2 characters."
         }
    }
  });
    });

第2-8行分别验证每个字段。正确填写所有字段后(根据我为每个字段设置的规则),删除btn-disabled类并启用按钮,以便客户可以折叠当前面板/切换下一个(和因此,请转到结帐表单的下一部分。)

还有一个方面让我烦恼:如果用户填写所有字段并刷新页面(或导航到另一个页面然后返回),即使字段先前已经过验证,它们也会显示为无效下一页加载(即使它们是正确/有效的)。我使用localstorage来保留数据,因此用户无需每次都输入数据。无论如何,我设法使用以下代码段验证页面加载时以前验证过的字段:

jQuery(window).load(function() {
    //pre-highlight fields with values
    jQuery('input[type=text], input[type=email], input[type=url], input[type=password], select').filter(function() {
        return jQuery.trim($(this).val()) != '';
    }).blur();
});

希望它有所帮助!