I’m using jQuery with the validate plug-in to validate a form. I’m also using jQuery-ui’s autocomplete to provide a list of acceptable values for one of the fields. Two fields, prov_type and prov_date control the content of the autocomplete list. prov_type is a radio button and prov_date is a text input with datepicker attached.
Goals
- Show message from failed
hasantecedentrule in a different place from normal rules - Show
hasantecedentfailure message only once, even though it applies to 2 fields
Problem
I have added prov_type and prov_date to $.validator.groups as “hasant” which accomplishes the second goal. The issue is that they are really only a group for the hasantecedent rule. Any other rules applied to them (e.g. date validation on prov_date) should really act as though the elements weren’t grouped. I think this probably can be addressed either in errorPlacement or in showError but I can’t figure out how.
Ideas?
Code
validation defaults
$.validator.setDefaults({
debug: true,
ignore: ":hidden", // do not validate form fields in invisible sections
focusCleanup: true,
errorPlacement: function(error, element) {
//something here to determine for placement of group rules?
if ( element.is(":radio") ) {
error.appendTo( element.parent().next().next() );
}else if(element.is(":checkbox") && element.parent().is('li')){
error.insertBefore(element.closest("ul.horiz"));
}else{
error.appendTo(element.parent());
};
},
success:'checked',// set this class to error-labels to indicate valid fields
validClass:'checked'//set this to same so valid class will be removed from fields that become errors
});
hasantecedent rule
$.validator.addMethod("hasantecedent", function( value, element ) {
set_possible_antecedents();
var type=$('input[name="prov_type"]:checked').val();
var r = $('#prov_date').data(type).length;
if(r){
$('.antecedent',$('#'+ type)).removeAttr('disabled');
} else {
$('.antecedent',$('#'+ type)).attr('disabled','disabled');
}
return r;
}, 'No fish are available for the current provenance date.');
form validation
$("form[name='provenance']").validate({
onkeyup: function(element, event){ //no keyup validation for fields with UI widgets
if(jQuery.inArray( element.name,['prov_date','dam', 'sire','reuse'])>-1) return;
$.validator.defaults.onkeyup.call(this, element, event);
},
groups:{hasant: 'prov_type prov_date'},
rules: {
prov_type: {hasantecedent: {depends: function(e){ return jQuery.inArray( $('input[name="prov_type"]:checked').val(),['cross','reuse']) > -1;}}},
prov_date: {
dateCan:true,
hasantecedent: {
depends: function(e){return jQuery.inArray( $('input[name="prov_type"]:checked').val(),['cross','reuse']) > -1;}
}
},
fish_id: { required: true, pkey: true},
dam_id: {
required: function(e) {return $('input[name="prov_type"]:checked').val()=='cross';},
pkey: true
},
sire_id: {
required: function(e) {return $('input[name="prov_type"]:checked').val()=='cross';},
pkey: true
},
dam: {
required: function(e) {return $('input[name="prov_type"]:checked').val()=='cross';},
isantecedent: {
depends: function(e){return $('input[name="prov_type"]:checked').val()=='cross';}
}
},
sire:{
required: function(e) {return $('input[name="prov_type"]:checked').val()=='cross';},
isantecedent: {
depends: function(e){return $('input[name="prov_type"]:checked').val()=='cross';}
},
},
dam_count: {
digits: function(e) {return $('input[name="prov_type"]:checked').val()=='cross';},
min:0
},
sire_count: {
digits: function(e) {return $('input[name="prov_type"]:checked').val()=='cross';},
min:0
},
supplier_id:{
required: function(e) {return $('input[name="prov_type"]:checked').val()=='delivery';},
pkey: true
},
removal_id:{
required: function(e) {return $('input[name="prov_type"]:checked').val()=='reuse';},
pkey: true
},
removal: {
required: function(e) {return $('input[name="prov_type"]:checked').val()=='reuse';},
isantecedent: {
depends: function(e){return $('input[name="prov_type"]:checked').val()=='reuse';}
}
},
}
});
What I ended up having to do is remove the
hasantgroup, add a static#hasantdiv where the message could go, and add a toggle vis to thehasantecedentrule. Like this:javascript
css
html