我正在尝试创建一项调查,员工可以在完成电话后填写该调查,该调查将用于跟踪交互期间销售的产品或服务。表单可以将无限数量的帐户附加到帐户包装器,并且每个帐户可以将无限数量的贷款附加到其贷款包装器。我正在使用JörnZaefferer的验证插件在提交之前验证调查;但是,该插件仅验证最近添加到表单的帐户。
如何让插件验证整个表单?
我学到的东西:我很笨,复选框应该使用REQUIRE而且永远不需要来自群组
以下是我用于表单的代码。
<form id="survey" method="GET" action="/processSurvey">
<h1>What products/services were completed during the call?</h1>
<div id="account-wrapper">
</div><!-- End Account Wrapper -->
<button type="submit">Submit</button> <button type="button" onclick="addAccount();">Add Account</button>
<input type="hidden" name="callID" value="0" />
</form>
我使用下面的把手模板动态地将帐户附加到帐户包装器:
<script id="account-template" type="text/x-handlebars-template">
<div id="account-{{id}}" class="account">
<div class="account-title ui-state-active">Account<button type="button">Remove Account</button></div>
<div class="service-wrapper">
<div class="service-container">
<span class="title">Account</span>
{{#each account}}
<span class="service-option">
<input type="checkbox" class="service service-group-{{accountID}}" name="account[{{accountID}}][service][]" value="{{value}}" /> {{html}}
</span>
{{/each}}
</div>
<div class="service-container">
<span class="title">Savings</span>
{{#each savings}}
<span class="service-option">
<input type="checkbox" class="service service-group-{{accountID}}" name="account[{{accountID}}][service][]" value="{{value}}" /> {{html}}
</span>
{{/each}}
</div>
<div class="service-container">
<span class="title">Checking</span>
{{#each checking}}
<span class="service-option">
<input type="checkbox" class="service service-group-{{accountID}}" name="account[{{accountID}}][service][]" value="{{value}}" /> {{html}}
</span>
{{/each}}
</div>
<div class="service-container">
<span class="title">Cards</span>
{{#each cards}}
<span class="service-option">
<input type="checkbox" class="service service-group-{{accountID}}" name="account[{{accountID}}][service][]" value="{{value}}" /> {{html}}
</span>
{{/each}}
</div>
<div class="service-container">
<span class="title">Other</span>
<textarea class="service service-group-{{id}}" name="account[{{id}}][service][]"></textarea>
</div>
<div class="error-container"></div>
</div>
<div id="loan-wrapper-{{id}}" class="loan-wrapper">
<div class="loan-title">Loans<button type="button" onclick="addLoan({{id}});">Add Loan</button></div>
<div class="loan-container"></div>
</div>
</div>
</script>
整个JavaScript:
$(document).ready(function(){
addAccount();
});
$(":button").button();
var loanCounter = 0;
var accountCounter = 0;
$.validator.addMethod("require_from_group", function(value, element, options) {
var validator = this;
var selector = options[1];
var validOrNot = $(selector, element.form).filter(function() {
return validator.elementValue(this);
}).length >= options[0];
if(!$(element).data('being_validated')) {
var fields = $(selector, element.form);
fields.data('being_validated', true);
fields.valid();
fields.data('being_validated', false);
}
return validOrNot;
}, $.format("Please select at least {0} product/service above (or fill in other)."));
$.validator.addMethod("ignorePlaceholder", function(value,element){
return this.optional(element) || (value !== element.placeholder);
},"This field is required.");
$.validator.addClassRules("required", {
ignorePlaceholder: true,
required: true
});
var validator = $("#survey").validate({
debug: true,
errorClass: "error",
validClass: "valid",
submitHandler: function(form){
form.submit();
},
invalidHandler: function(){
alert(validator.numberOfInvalids());
},
errorPlacement: function(error, element){
if($(element).hasClass("service")){
error.appendTo($(element).parents(".service-wrapper").children("div.error-container"));
}
},
rules: {
}
});
function addAccount(){
var newAccount = {
id:accountCounter,
account:[
{value:"1",html:"New Account",accountID:accountCounter},
{value:"13",html:"eStatements",accountID:accountCounter}
],
savings:[
{value:"2",html:"My Choice",accountID:accountCounter},
{value:"3",html:"Money Market",accountID:accountCounter},
{value:"4",html:"Individual Reitrement Account",accountID:accountCounter},
{value:"5",html:"Individual Retirement Account (Certificate of Deposit)",accountID:accountCounter},
{value:"6",html:"Certificate of Deposit",accountID:accountCounter}
],
checking:[
{value:"7",html:"Prosper Checking",accountID:accountCounter},
{value:"8",html:"ePerks Checking",accountID:accountCounter},
{value:"9",html:"Protect Checking",accountID:accountCounter},
{value:"10",html:"Basic Checking",accountID:accountCounter}
],
cards:[
{value:"11",html:"Credit Card",accountID:accountCounter},
{value:"12",html:"Debit Card",accountID:accountCounter}
]
}
var template = Handlebars.compile($("#account-template").html());
var result = template(newAccount);
$("#account-wrapper").append(result);
$("#account-wrapper .account:last :button").button();
$("#account-wrapper .account:last div.account-title :button").click(function(){
$(this).parents("div.account").remove();
});
$("#account-"+accountCounter).placeholder();
$("html, body").animate({scrollTop: $("#account-"+accountCounter).offset().top},1000);
$(".service-group-"+accountCounter).each(function() {
$(this).rules('add', {
require_from_group: [1, ".service-group-"+accountCounter]
});
});
accountCounter++;
}
请注意顶部表单无效,因为我没有选中选项。如果我添加相同的帐户模板并选中一个选项,表单将会提交。
jsFiddle&lt; - 链接到问题的工作副本。请注意表单只关心最近添加的帐户是否有效。
答案 0 :(得分:1)
我想我终于看到这里出了什么问题。
您不应该使用.addClassRules()
方法,因为这仅用于创建分配给class
的复合规则。
相反,您应该使用the .rules('add')
method,这是为了动态声明新元素的规则。
function addAccount(){
var newAccount = {
// your code
....
}
// your code
.....
// add the rule to every element in the newly created group
var group = ".service-group-" + accountCounter;
$(group).each(function() {
$(this).rules('add', {
require_from_group: [1, group],
messages: {
require_from_group: "this is a custom message"
}
});
});
accountCounter++;
}
修改强>:
我相信OP在他实现它的复杂方式中发现了require_from_group
方法的另一个错误。
但是,在required
群组中使用标准checkbox
规则,默认情况下 ,只需要群组中的一个项目。换句话说,只要组中的所有复选框共享相同的name
(就像通常那样),您只需要检查一个项目。
这是OP的演示经过修改,删除了require_from_group
方法并将其替换为标准required
规则。我还修改了他的模板,以便一个帐户部分中的所有checkbox
元素将共享相同的name
。它似乎现在正在运作: