Extjs - Multi validations VType email - extjs

I've a probllem with email textfield on which I want to perform multi validations. In detail:
1. Classic format email validation
2. Unique email check
Can I override email VType? or I have to create a custom VType? How can I perform two validation with two different error messages in a single VType?
Thanks
Regards

You can override the default validation using the validator attribute. For example, if you wish to enforce the standard rules and some other rules (e.g. defined by isSomeOtherRules() that returns a boolean), set the following attribute:
validator: function(value) {
return Ext.form.VTypes.email(value) && isSomeOtherRules(value);
}

Expanding on Andrew's post; we can return validation messages (shown below) to get the same look and feel of vtype error alert:
validator: function(value) {
if (!Ext.form.VTypes.cfpValidatePdf(value)) {
return 'File must be pdf';
} else if (!Ext.form.VTypes.cfpValidateFileNameSize(value)) {
return 'The maximum length of the filename is 64';
} else {
return true;
}
}

Related

How to validate with regular expression and display error message in xeditable

I am using xeditable in my project.
I need to validate each and every field,
how to do validation using ng-pattern="/^[a-zA-Z ]*$/" and show error message if the input value does not match the pattern.
can any one guide me how can i proceed with this.
Fiddle
$scope.checkName = function(data) {
console.log("user.name.onbeforesave:", data)
if (data !== 'awesome') {
return "Username should be `awesome`";
}
};
Do you need to use ng-pattern? Can you not change the function to use the regexp?
This works:
$scope.checkName = function(data) {
console.log("user.name.onbeforesave:", data)
if (!data.match(/^[a-zA-Z ]*$/)) {
return "Only spaces and letters allowed";
}
}

cakephp validation to ensure null field

In my scenario I have a rest controller that I am validating input data.
I have built a form that I am using purely for custom validation that looks like this:
$validator
->requirePresence('sport_type')
->add('sport_type', 'Require fields missing', [
'rule' => function ($value) {
switch ($value) {
case 'Football':
$this->validator()
->requirePresence('football_id');
break;
case 'Basketball':
$this->validator()
->requirePresence('basketball_id');
break;
default:
return true;
}
return true;
}
])
->notEmpty('football_id')
->notEmpty('basketball_id')
return $validator;
What I need to be able to do, is in the default case, ensure that the other fields are null - if for example, sport_type = 'Motorsport', then the validator must return false if the input data DOES contain something in football_id or basketball_id.
I cannot see any kind of requireEmpty type of method in cake, so can anyone suggest how to accomplish this. Do I need a separate custom validator for that single rule, and how would I call it from this form validator ?

Is there a way for comparing dates on Valdr?

I'm using Valdr on my project and I need to validate that a date input "startDate" is before another date input "endDate".
<input id="startDate" name="startDate" type="text" ng-model="project.startDate"/>
<input id="endDate" name="endDate" type="text" ng-model="project.endDate"/>
I know that, without Valdr, this problem can be solved using a custom directive, as shown here: Directive for comparing two dates
I found a little unclear how to create a custom validator on Valdr that uses the values of other fields.
The answer is short but dissatisfactory: valdr does currently not support this. There is an open feature request on GitHub, though.
Until the feature gets implemented in valdr, you can use your own validator directive and kind of make it talk to valdr. The directive can require a 'form' and can get the names of the date models you want to compare. Then you do your logic to compare the two values and set the validity of the appropriate 'ngModelController'. Since you need to provide an error when setting the validity to that model, the error name will be your connection with valdr.
After that, you just only need to map the error in the 'valdrMessage' service:
.run(function (valdrMessage) {
valdrMessage.angularMessagesEnabled = true;
valdrMessage.addMessages({
'date': 'Invalid date!'
});
});
Valdr will show the message bellow the invalid field as usual.
Actually you can solve this through a custom validator, which can get another field and compare the values with each other. The code below is using the valdr-bean-validation for serverside generation of valodation.json.
If you want to use it without this, just look into the JS code and add the validator in your validation.json manually.
Java Annotation (serverside declaration of the valdr validator):
package validation;
#Documented
#Retention(RetentionPolicy.RUNTIME)
#Target({ ElementType.METHOD, ElementType.FIELD, ElementType.CONSTRUCTOR,
ElementType.PARAMETER, ElementType.ANNOTATION_TYPE })
public #interface DateFormat {
String message();
Class[] groups() default { };
String beforeFieldName();
}
Java Bean (usage of the annotation, this class has to be used in the generation of validation.json):
package pojo;
import validation.DateFormat;
public class RegistrationPojo implements BasePojo {
#NotNull(message = "message.date1.required")
private Date date1;
#NotNull(message = "message.date2.required")
#DateFormat(message = "message.date2.date", beforeFieldName = "date1")
private Date date2;
}
JS (implementation of the custom validator and registering it in valdr):
module.factory('validation.DateFormat', [
function () {
return {
name: 'validation.DateFormat',
validate: function (value, constraint) {
var minOk = true;
var maxOk = true;
var format = false; // constraint.pattern is mandatory
//do not validate for required here, if date is null, date will return true (valid)
console.log("my date validator called");
console.log(" beforeFieldName: " + constraint.beforeFieldName);
var field = document.querySelector('[name="' + constraint.beforeFieldName + '"]');
console.log("field value: " + (field ? field.value : "null"));
return (!field || value > field.value);
}
};
}]);
module.config([
"valdrProvider",
function(valdrProvider) {
valdrProvider.addValidator('validation.DateFormat');
}]);
You could go with this solution:
Have a bool value calculated upon changes in any of the date fields - a value indicating if the validation rule is met
Create a simple custom validator to check if that value is true or not
Register your validator and add a constraint for that calculated value
Place a hidden input for that calculated value anywhere you like your validation message to appear

Backbone: validating attributes one by one

I need to validate a form with a bunch of inputs in it. And, if an input is invalid, indicate visually in the form that a particular attribute is invalid. For this I need to validate each form element individually.
I have one model & one view representing the entire form. Now when I update an attribute:
this.model.set('name', this.$name.val())
the validate method on the model will be called.
But, in that method I am validating all the attributes, so when setting the attribute above, all others are also validated, and if any one is invalid, an error is returned. This means that even if my 'name' attribute is valid, I get errors for others.
So, how do I validate just one attribute?
I think that it is not possible to just validate one attribute via the validate() method. One solution is to not use the validate method, and instead validate every attribute on 'change' event. But then this would make a lot of change handlers. Is it the correct approach? What else can I do?
I also think that this points to a bigger issue in backbone:
Whenever you use model.set() to set an attribute on the model, your validation method is run and all attributes are validated. This seems counterintuitive as you just want that single attribute to be validated.
Validate is used to keep your model in a valid state, it won't let you set an invalid value unless you pass a silent:true option.
You could either set all your attributes in one go:
var M=Backbone.Model.extend({
defaults:{
name:"",
count:0
},
validate: function(attrs) {
var invalid=[];
if (attrs.name==="") invalid.push("name");
if (attrs.count===0) invalid.push("count");
if (invalid.length>0) return invalid;
}
});
var obj=new M();
obj.on("error",function(model,err) {
console.log(err);
});
obj.set({
name:"name",
count:1
});
or validate them one by one before setting them
var M=Backbone.Model.extend({
defaults:{
name:"",
count:0
},
validate: function(attrs) {
var invalid=[];
if ( (_.has(attrs,"name"))&&(attrs.name==="") )
invalid.push("name");
if ( (_.has(attrs,"count"))&&(attrs.count===0) )
invalid.push("count");
if (invalid.length>0) return invalid;
}
});
var obj=new M();
obj.on("error",function(model,err) {
console.log(err);
});
if (!obj.validate({name:"name"}))
obj.set({name:"name"},{silent:true});
I recently created a small Backbone.js plugin, Backbone.validateAll, that will allow you to validate only the Model attributes that are currently being saved/set by passing a validateAll option.
https://github.com/gfranko/Backbone.validateAll
That is not the issue of Backbone, it doesn't force you to write validation in some way. There is no point in validation of all attributes persisted in the model, cause normally your model doesn't contain invalid attributes, cause set() doesn't change the model if validation fails, unless you pass silent option, but that is another story. However if you choose this way, validation just always pass for not changed attributes because of the point mentioned above.
You may freely choose another way: validate only attributes that are to be set (passed as an argument to validate()).
You can also overload your model's set function with your own custom function to pass silent: true to avoid triggering validation.
set: function (key, value, options) {
options || (options = {});
options = _.extend(options, { silent: true });
return Backbone.Model.prototype.set.call(this, key, value, options);
}
This basically passes {silent:true} in options and calls the Backbone.Model set function with {silent: true}.
In this way, you won't have to pass {silent: true} as options everywhere, where you call
this.model.set('propertyName',val, {silent:true})
For validations you can also use the Backbone.Validation plugin
https://github.com/thedersen/backbone.validation
I had to make a modification to the backbone.validation.js file, but it made this task much easier for me. I added the snippet below to the validate function.
validate: function(attrs, setOptions){
var model = this,
opt = _.extend({}, options, setOptions);
if(!attrs){
return model.validate.call(model, _.extend(getValidatedAttrs(model), model.toJSON()));
}
///////////BEGIN NEW CODE SNIPPET/////////////
if (typeof attrs === 'string') {
var attrHolder = attrs;
attrs = [];
attrs[attrHolder] = model.get(attrHolder);
}
///////////END NEW CODE SNIPPET///////////////
var result = validateObject(view, model, model.validation, attrs, opt);
model._isValid = result.isValid;
_.defer(function() {
model.trigger('validated', model._isValid, model, result.invalidAttrs);
model.trigger('validated:' + (model._isValid ? 'valid' : 'invalid'), model, result.invalidAttrs);
});
if (!opt.forceUpdate && result.errorMessages.length > 0) {
return result.errorMessages;
}
}
I could then call validation on a single attribute like so
this.model.set(attributeName, attributeValue, { silent: true });
this.model.validate(attributeName);

ExtJS vtype as a function

Is there any way to test a vType on a value, without it being in a form?
Eg I have a custom vtype implemented to do ajax validation, however I would also like to run it against the email vtype, so I was hoping to run something inside my custom vtype along the lines of
validate('abc#de.ce','email');
You could use functions instead of properties, then you could just call 'em:
Ext.apply(Ext.form.VTypes, {
// Validates an ajax thingy
ajax: function(v) {
// validate against email VType
return Ext.form.VTypes.email(v);
},
// Override the default Ext function, to allow oddly-placed hyphens
email: function(v) {
var regex = /^[-\w][-+\.\w]*#[-\w\.]+\.[A-Za-z]{2,4}$/;
return regex.test(v);
}
}
Ext.form.VTypes.ajax('abc#de.ce');

Resources