I have the following validation code...
jQuery('#MyForm').validate({
ignore: ".ignore",
rules: {
FirstName: {
required: function () { //this works
return (document.getElementById("FirstName").value === '');
}
},
LastName: {
required: true //this doesn't work
}
...
For some reason, if I specify the rules like "LastName" above, it doesn't work. However if I put a function to explicitly validate the field, like "FirstName", it does work.
Can anyone suggest a possible reason for this?
Either style works fine in other browsers.
Some other questions have suggested adding "X-UA-Compatible" meta tag, but that makes no difference in this case.
After some further investigation, I can see that it's erroring in jquery.validate.js, at this line...
settings[ eventType ].call( validator, this, event );
in this block of code...
var validator = $.data( this.form, "validator" ),
eventType = "on" + event.type.replace( /^validate/, "" ),
settings = validator.settings;
if ( settings[ eventType ] && !$( this ).is( settings.ignore ) ) {
settings[ eventType ].call( validator, this, event );
}
There seems to be an issue with jQuery Validate v1.18.0, I've downgraded to 1.17.0, and it's working correctly again.
Related
I'm trying to add a validator to a form field in ExtJS 6.5.3.57 Classic or Modern. I thought from reading various posts that this should work, but when I run myField.isValid() it always returns true, and I don't see my console.log() statement firing so I have to assume my function isn't getting called.
{xtype: numberfield,
name: 'myField',
validator: function(field){
console.log('testing my validator');
return false;
}
}
I also tried this as I wasn't sure if it was validator or validators
{xtype: numberfield,
name: 'myField',
validators: {
fn: function(field){
console.log('testing my validator');
return false;
}
}
}
Am I wrong in thinking this should work?
Here's a fiddle showing that the top field in the login form which has a validator on it but never seems to log a message to the screen or console. https://fiddle.sencha.com/#fiddle/2eoa
The second example you gave is valid, I've made a working fiddle:
Ext.application({
name : 'Fiddle',
launch : function() {
Ext.Viewport.add({
xtype: 'textfield',
validators: {
fn: function(v) {
return v === 'abc' || 'Value must be abc'
}
}
});
}
});
I am trying to create a conditional required validation on a specific field.I try doing this by return Validators.required back in my function, but this doesn't seem to work. How do I go about doing this? Here's my code:
private _ansat: AbstractControl = new FormControl('', Validators.required);
private _helbred: AbstractControl = new FormControl('', Validators.compose([this.useValidateIfRadio(this._ansat, 0, Validators.required)]) );
constructor(private _fb: FormBuilder) {
this.myForm = this._fb.group({
ansat: this._ansat,
helbred: this._helbred
});
}
useValidateIfRadio (c: AbstractControl, n: number, v) {
return function (control) {
return new Promise(resolve => {
// this.msg = ansatControl.value;
console.log(v);
if (c.value === n) {
resolve(v);
}
else {
resolve(null);
}
});
};
};
Any help is greatly appreciated.
I had a similar problem but couldn't find a answer. Since nobody has answered this yet I'll provide an example of how I solved my problem, and how you can solve your issue using the same solution.
Example: (Phone number is required only if email is not set)
export class UserComponent implements OnInit {
userForm: FormGroup;
constructor(private fb: FormBuilder) {}
ngOnInit() {
//Create my userForm and and add initial validators
this.userForm = this.fb.group({
username: [null, [Validators.required]],
name: [null, [Validators.required]],
email: [],
phoneNumber: [null, [Validators.required, Validators.minLength(4)],
});
//Listen to email value and update validators of phoneNumber accordingly
this.userForm.get('email').valueChanges.subscribe(data => this.onEmailValueChanged(data));
}
onEmailValueChanged(value: any){
let phoneNumberControl = this.userForm.get('phoneNumber');
// Using setValidators to add and remove validators. No better support for adding and removing validators to controller atm.
// See issue: https://github.com/angular/angular/issues/10567
if(!value){
phoneNumberControl.setValidators([Validators.required, Validators.minLength(4)]);
}else {
phoneNumberControl.setValidators([Validators.minLength(4)]);
}
phoneNumberControl.updateValueAndValidity(); //Need to call this to trigger a update
}
}
So in your case you should add a changeListener to "_ansat" equal to my email listener, and then add required to "_helbred" accordingly.
Just add validator for the field:
if(some_logic) {
this.your_form.get('field_name').setValidators([Validators.required]);
}
These answers got me most of the way there, but I found out a pretty big gotcha… in some cases, setValidators only adds to the existing array of validators and does not work well to clear them. In some cases, like when ngOnInit loads twice in a row, the conditions could be first negative and then positive for a passed-in value you're depending on. In such a case, you will set it to required, then later attempt to clear it, but the UI will still behave like it expects it. To fix this, consider the following...
const myControl = this.your_form.get('field_name');
if(some_logic) {
myControl.clearAsyncValidators();
myControl.clearValidators();
myControl.updateValueAndValidity({onlySelf:true});
} else {
myControl.setValidators([Validators.required, Validators.other…]);
}
I'm using mongoose and trying to set a custom validation that tells the property shall be required (ie. not empty) if another property value is set to something. I'm using the code below:
thing: {
type: String,
validate: [
function validator(val) {
return this.type === 'other' && val === '';
}, '{PATH} is required'
]}
If I save a model with {"type":"other", "thing":""} it fails correctly.
If I save a model with {"type":"other", "thing": undefined} or {"type":"other", "thing": null} or {"type":"other"} the validate function is never executed, and "invalid" data is written to the DB.
As of mongoose 3.9.1, you can pass a function to the required parameter in the schema definition. That resolves this problem.
See also the conversation at mongoose: https://github.com/Automattic/mongoose/issues/941
For whatever reason, the Mongoose designers decided that custom validations should not be considered if the value for a field is null, making conditional required validations inconvenient. The easiest way I found to get around this was to use a highly unique default value that I consider to be "like null".
var LIKE_NULL = '13d2aeca-54e8-4d37-9127-6459331ed76d';
var conditionalRequire = {
validator: function (value) {
return this.type === 'other' && val === LIKE_NULL;
},
msg: 'Some message',
};
var Model = mongoose.Schema({
type: { type: String },
someField: { type: String, default: LIKE_NULL, validate: conditionalRequire },
});
// Under no condition should the "like null" value actually get persisted
Model.pre("save", function (next) {
if (this.someField == LIKE_NULL) this.someField = null;
next()
});
A complete hack, but it has worked for me so far.
Try adding this validation to the type attribute, then adjust your validation accordingly. E.g.:
function validator(val) {
val === 'other' && this.thing === '';
}
thing: {
type: String,
required: function()[{
return this.type === 'other';
}, 'YOUR CUSTOM ERROR MSG HERE']
}
I am running into issue when trying to do :
newNoteText: ko.observable().extend({ required: { onlyIf: function () { return this.ShowNote == true } } })
I noticed that this doesn’t work, but when I put the code back like this, it works fine:
newNoteText: ko.observable().extend({ required: true })
http://sdrv.ms/WJC3fS
https://skydrive.live.com/redir?resid=33048714B5BF3B4B!2027
The proper syntax to use the onlyIf option on a rule is :
newNoteText: ko.observable().extend({
required: {
onlyIf: function(){
return someFlagIsTrue;
}
}
Cf. this answer to one of your previous questions (by Eric Barnard, main contributor to Knockout Validation).
Regarding, your code, apart from Knockout Validation's syntax, there are two other things to worry about :
return something == true is the same as return something (not mentioning JavaScript's way of handling == and === operators, see more about this here).
In your function the value of this isn't what you seem to think it is (here it refers to the parameter between the parenthesis of extend()).
If you want to access the value of one of the other observables of your view model, you should be doing something like :
newNoteText: ko.observable().extend({
required: {
onlyIf: function(){
return self.ShowNote();
}
}
Where self is defined at the top of your view model constructor, like var self = this;. See more about this pattern here.
The params option mentioned by ThibWeb isn't needed - knockout.validation.js sets this by default to true in the addExtender method:
if (params.message || params.onlyIf) {
return ko.validation.addRule(observable, {
rule: ruleName,
message: params.message,
params: utils.isEmptyVal(params.params) ? true : params.params,
condition: params.onlyIf
});
The Eric Barnard answer was in 2011, presumably before this was defaulted to true.
However, if your code sets any validation defaults, you might be writing an HTML5 required attribute into the HTML, or reading one that is set in the HTML:
ko.validation.configure({
parseInputAttributes: true, //default is false
writeInputAttributes: true //default is false
});
I've found this causes an onlyIf required condition to be effectively ignored, since you are adding an extra required rule which is always applied.
According to the documentation for the JQuery validation plugin:
the validation is lazy: Before submitting the form for the first time, the user can tab through fields without getting annoying messages
Is there any way to display the messages as the user tabs through the form?
Cheers
You can override the default onfocusout to do more eager/pre-submit validation you want, like this:
$(function() {
$("form").validate({
rules: { ...rules... },
messages: { ...messages... },
onfocusout: function(element) { $(element).valid(); }
});
});
The default onfocusout looks like this, disabling the blur validation until after it's been submitted once:
onfocusout: function(element) {
if ( !this.checkable(element) && (element.name in this.submitted || !this.optional(element)) ) {
this.element(element);
}
}