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

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";
}
}

Related

How to view the ParsleyJS errors without blocking form submition

Is there a way to get the list of errors from parsley.js? I have a form that has one field that I want validate and give feedback to the user as a warning, but I don't want the error state for that field to block form submission. I am handling the form submission myself, so I'm looking for something like
$("form[name='client']").on('submit'), function(e) {
e.preventDefault();
var form = $(this);
form.parsley().validate();
// pseudo code as I don't know how to do this yet with parsley
var errors = form.parsley().errors().filter(function(err) { return err.field != field_to_ignore })
if (errors.length ) {
// error handling
} else {
// submit form
}
});
You could change the inputs or excluded options when you click on submit so that your inputs are all excluded.
My Solution is to work with two validations:
1.The first one is binding the error to the UI.
2.The second one is after adding the data-parsley-excluded=true attribute to your field_to_be_ignore.
$("#myForm").on('submit'), function(e) {
e.preventDefault();
var form = $(this);
//the first validation bind the error message to the screen
if (form.parsley().validate() == false) {
$('myFieldToIgnore').attr('data-parsley-excluded','true');
//Now let make a second validation:
form.parsley().validate();
}
else {
//submit
}
});

Enable/disable validation for angular form with nested subforms using `ng-form`

I need to enable/disable all validation rules in Angular form or subform under ng-form="myForm" based on a scope variable $scope.isValidationRequired. So, if isValidationRequired is false, none of the validations set for the designated group of fields will run, and the result will always be myForm.$valid==true, otherwise, the validation rules will run as usual.
I did a lot of research, and realized that this feature is not available out of the box with Angular. However, I found some add-ons or with some customization, it is possible.
For example, I can use the add-on angular-conditional-validation (github and demo) with custom directive enable-validation="isValidationRequired". This will be perfect, except that I cannot apply this feature for a group of fields under ng-form. I have to add this directive for each and every field where applicable.
The other solution is to use custom validation using Angular $validators pipeline. This requires some extra effort and I don't have time since the sprint is almost over and I have to give some results in a few days.
If you have any other suggestions please post an answer.
Use Case:
To clarify the need for this, I will mention the use-case. The end user can fill the form with invalid data and he can click Save button and in this case, the validation rules shouldn't be triggered. Only when the user clicks Validate and Save then the validation rules should be fired.
Solution:
See the final plunker code here.
UPDATE: as per comments below, the solution will cause the browser to hang if inner subforms are used under ng-form. More effort is needed to debug and resolver this issuer. If only one level is used, then it works fine.
UPDATE: The plunker here was updated with a more general solution. Now the code will work with a form that has sub-forms under ng-form. The function setAllInputsDirty() checks if the object is a $$parentForm to stop recursion. Also, the changeValidity() will check if the object is a form using $addControl then it will call itself to validate its child objects. So far, this function works fine, but it needs a bit of additional optimization.
One idea is to reset the errors in the digest loop if the validation flag is disabled. You can iterate through the form errors on change and set them to valid, one by one.
$scope.$watch(function() {
$scope.changeValidity();
}, true);
$scope.changeValidity = function() {
if ($scope.isValidationRequired === "false") {
for (var error in $scope.form.$error) {
while ($scope.form.$error[error]) {
$scope.form.$error[error][0].$setValidity(error, true);
}
}
}
}
Here is a plunkr: https://plnkr.co/edit/fH4vGVPa1MwljPFknYHZ
This is the updated answer that will prevent infinite loop and infinite recursion. Also, the code depends on a known root form which can be tweaked a bit to make it more general.
References: Pixelastic blog and Larry's answer
Plunker: https://plnkr.co/edit/ycPmYDSg6da10KdoNCiM?p=preview
UPDATE: code improvements to make it work for multiple errors for each field in each subform, and loop to ensure the errors are cleared on the subform level
var app = angular.module('plunker', []);
app.controller('MainCtrl', ["$scope", function($scope) {
$scope.isValidationRequired = true;
var rootForm = "form";
function setAllInputsDirty(scope) {
angular.forEach(scope, function(value, key) {
// We skip non-form and non-inputs
if (!value || value.$dirty === undefined) {
return;
}
// Recursively applying same method on all forms included in the form except the parent form
if (value.$addControl && key !== "$$parentForm") {
return setAllInputsDirty(value);
}
if (value.$validate){
value.$validate();
}
// Setting inputs to $dirty, but re-applying its content in itself
if (value.$setViewValue) {
//debugger;
return value.$setViewValue(value.$viewValue);
}
});
}
$scope.$watch(function() {
$scope.changeValidity();
}, true);
$scope.changeValidity = function(theForm) {
debugger;
//This will check if validation is truned off, it will
// clear all validation errors
if (!theForm) {
theForm = $scope[rootForm];
}
if ($scope.isValidationRequired === "false") {
for (var error in theForm.$error) {
errTypeArr = theForm.$error[error];
angular.forEach (errTypeArr, function(value, idx) {
var theObjName = value.$name;
var theObj = value;
if (theObj.$addControl) {
//This is a subform, so call the function recursively for each of the children
var isValid=false;
while (!isValid) {
$scope.changeValidity(theObj);
isValid = theObj.$valid;
}
} else {
while (theObj.$error[error]) {
theObj.$setValidity(error, true);
}
}
})
}
} else {
setAllInputsDirty($scope);
}
}
}]);

AngularJS: searching data client side by custom filter

i am learning angular. so i am not good in angular. i am showing data in tabular format with the help of ng-repeat. i have one dropdown and textbox for filter data showing by ng-repeat. fields name are populated in dropdown. so user will select field name and put corresponding value in textbox and search will perform accordingly and data will be shown.
my code is working partially. basically some kind of problem is there in SearchList function. the problem is when trying to search by id then SearchList is not working properly. so looking for help. what to fix in the code. my js fiddle https://jsfiddle.net/tridip/rnoo3bqc/6/
$scope.SearchList = function(row) {
if ($scope.selectedFieldName && $scope.searchText) {
var propVal = row[$scope.selectedFieldName.toLowerCase()];
if (propVal) {
return propVal.toUpperCase().indexOf($scope.searchText.toUpperCase()) > -1;
} else {
return false;
}
}
return true;
};
working version url
https://jsfiddle.net/tridip/rnoo3bqc/8/
You need to convert the id's from number to string, e.g. by concatenating an empty string:
var propVal = row[$scope.selectedFieldName.toLowerCase()] + '';
the problem was with id that's a numeric field and hence toUpperCase() was failing for it.
if (propVal) {
propVal.toString().toUpperCase().indexOf($scope.searchText.toUpperCase()) > -1;
} else {
return false;
}

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

Extjs - Multi validations VType email

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;
}
}

Resources