Jquery.Validate - 根据哪个选项卡添加/删除规则

Jquery.Validate - Add / Remove Rules based on which tab

我有一个 Bootstrap 4 标签界面,每个标签上都有输入框。我想允许用户根据他们所在的选项卡输入不同的必填字段,因此我希望添加或删除基于该选项卡的验证。还有一些强制输入,无论用户在哪个选项卡中。

我所做的是创建一个添加 2 个共享输入及其规则的默认验证函数。然后,我使用 Bootstrap 事件来捕获单击了哪个选项卡,删除了所有现有验证并为该特定选项卡创建了验证。

虽然我最近注意到选项卡内的输入在来回切换时实际上并没有重置,但我已经完成了 90% 的工作。我曾尝试使用 addmethod,但根本无法使用新规则。

我的 Real life 应用有 2 个以上的标签,所以我也不能简单地在 2 组规则之间来回切换。

提琴手here

var currTab = '#tab1';
ValidationDefaults();
Tab1Validation();


$('a[data-toggle="tab"]').on('shown.bs.tab', function(e) {
  currTab = $(e.target).attr("href"); // activated tab

  ClearValidation();
  ValidationDefaults();

});

$('#btnSubmit').on('click', function(e) {

  switch (currTab) {
    case "#tab1":

      Tab1Validation();
      break;
    case "#tab2":

      Tab2Validation();
      break;
  }

  if ($("form").valid()) {

  }
});


function Tab1Validation() {

  //
  var validator = $("#Create").validate({
    rules: {
      username: {
        require_from_group: [1, ".Tab1Group"]
      },
      username2: {
        require_from_group: [1, ".Tab1Group"]
      }
    },
    messages: {
      username: "* You must enter either a username or a Username 2",
      username2: "* You must enter either a username or a Username 2"
    }
  });

}

function Tab2Validation() {

  //
  var validator = $("#Create").validate({
    rules: {
      street: {
        required: true
      },
      city: {
        required: true
      }
    },
    messages: {
      street: "* You must enter either a street",
      city: "* You must enter either a city"
    }
  });

}

function ClearValidation() {
  var validator = $("#Create").validate();
  validator.resetForm();

  $('#Create').removeData('validator');
  ValidationDefaults();
}

function ValidationDefaults() {

  $.validator.setDefaults({
    rules: {
      firstname: {
        required: true
      },
      lastname: {
        required: true
      }
    },
    messages: {
      firstname: "* A first name is Required",
      lastname: "* A last name is Required"
    },
    errorElement: 'span',
    errorPlacement: function(error, element) {
      error.addClass('invalid-feedback');
      element.closest('.form-group').append(error);
    },
    highlight: function(element, errorClass, validClass) {
      $(element).addClass('is-invalid');
    },
    unhighlight: function(element, errorClass, validClass) {
      $(element).removeClass('is-invalid');
    }
  });
}

你的尝试是错误的方法...

.validate() 方法只能调用 一次 以初始化表单上的插件,并且由于所有后续调用会被忽略,不能多次调用它来重写你的规则。

处理所有这些问题的正确方法是:

  1. 在页面加载时调用 .validate() 一次,然后
  2. 调用 .rules('add').rules('remove') 方法根据需要动态切换规则。

尝试这样的事情:jsfiddle DEMO

var currTab = '#tab1'
ValidationDefaults();  // INITIALIZE PLUGIN ON FORM
Tab1Validation();      // SETUP TAB 1 with RULES

$('a[data-toggle="tab"]').on('shown.bs.tab', function(e) {
    currTab = $(e.target).attr("href"); // activated tab
});

$('#btnSubmit').on('click', function(e) {
    switch (currTab) {
        case "#tab1":
            Tab1Validation();
            break;
        case "#tab2":
            Tab2Validation();
            break;
    }
    if ($("form").valid()) {

    }
});

function Tab1Validation() {
    // ADD RULES FOR TAB 1
    $('#tab1 input').each(function() {
        $(this).rules('add', {
            require_from_group: [1, ".Tab1Group"],
            messages: {
                require_from_group: "* You must enter either username or username2"
            }
        });
    });
    // REMOVE RULES FOR TAB 2
    $('#tab2 input').each(function() {
        $(this).rules('remove');
    });
}

function Tab2Validation() {
    // ADD RULES FOR TAB 2
    $('#tab2 input').each(function() {
        $(this).rules('add', {
            required: true,
        });
    });
    // REMOVE RULES FOR TAB 1
    $('#tab1 input').each(function() {
        $(this).rules('remove');
    });
}

function ValidationDefaults() {
    // INITIALIZE PLUGIN ON PAGE LOAD
    $('#Create').validate({
        rules: {
            firstname: {
                required: true
            },
            lastname: {
                required: true
            }
        },
        messages: {
            firstname: "* A first name is Required",
            lastname: "* A last name is Required"
        },
        // combine messages into one for "require_from_group"
        groups: {  
            tab1: "username username2"
        },
        errorElement: 'span',
        errorPlacement: function(error, element) {
            error.addClass('invalid-feedback');
            element.closest('.form-group').append(error);
        },
        highlight: function(element, errorClass, validClass) {
            $(element).addClass('is-invalid');
        },
        unhighlight: function(element, errorClass, validClass) {
            $(element).removeClass('is-invalid');
        }
    });
}

请注意,我使用 jQuery .each() 一次将所有规则应用于选项卡中的所有字段。如果您需要将唯一 rules/messages 应用于各个字段,请删除 .each() 并根据需要将 .rules() 附加到单个字段选择器。