jQuery Validator only validates most recent DOM element -
this question has answer here:
i trying create survey employees can fill out after completing phone call used track products or services sold during interaction. form can have infinite number of accounts appended account-wrapper , each account can have infinite number of loans appended loan wrapper. using jörn zaefferer's validation plugin validate survey before submitted; however, plugin validates account added form.
how plugin validate entire form?
what have learned: dumb , checkboxes should use require , never require group
here code use form.
<form id="survey" method="get" action="/processsurvey"> <h1>what products/services completed during 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> i dynamically append accounts account-wrapper using handlebars template below:
<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> entire 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 @ least {0} product/service above (or fill in other).")); $.validator.addmethod("ignoreplaceholder", function(value,element){ return this.optional(element) || (value !== element.placeholder); },"this field 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++; } notice how top form invalid because not have option checked. if add identical account template , check option, form submit.

jsfiddle <-- link working replica of problem. notice how form cares added account valid.
i think see what's going wrong here.
you should not using .addclassrules() method that's creating compound rule assigned class.
rather, should using the .rules('add') method, dynamically declaring rules on new elements.
function addaccount(){ var newaccount = { // code .... } // code ..... // add rule every element in newly created group var group = ".service-group-" + accountcounter; $(group).each(function() { $(this).rules('add', { require_from_group: [1, group], messages: { require_from_group: "this custom message" } }); }); accountcounter++; } edit:
i believe op found bug require_from_group method in complex way he's implementing it.
however, using standard required rule on checkbox group, by default, requires 1 item group. in other words, long checkboxes in group share same name (as do), you'll required check 1 item.
this op's demo modified remove require_from_group method , replace standard required rule. modified template checkbox elements within 1 account section share same name. seems working now:
Comments
Post a Comment