Angular password validation - angularjs

In my Angular 1.x app I have a password field set as follows:
<input class="form-control mb15 ng-not-empty ng-dirty ng-valid-parse ng-valid-required ng-valid ng-valid-pattern ng-touched" type="password" name="password" placeholder="Password" ng-model="user.password" ng-pattern="/^(?=.*[a-z])(?=.*[A-Z]).{8,}$/" required="required" data-validity-message="This field cannot be left empty" oninvalid="this.setCustomValidity(''); if (!this.value) this.setCustomValidity(this.dataset.validityMessage)" oninput="this.setCustomValidity('')" id="password">
My password confirm field is similar with a check that the two passwords match:
ng-class="{'has-error':userRegister.password_confirm.$dirty && user.password_confirm !== user.password}">
This works but the password and pasword_confirm are only evaluated once the ng-pattern regex is satisfied. So if I enter two short passwords which are invalid, the validation message incorrectly tells the user that the password do not match.
If I debug the value of user.password in my template it only shows a value once it is "valid".
I thought I might be able to solved this by also adding the ng-pattern directive to the password_confirm field but it seems this is not a proper solution.
How can I evaluate the two fields as being equal before the regex is satisfied?

https://docs.angularjs.org/api/ng/directive/ngModelOptions
The default behaviour in ngModel is that the model value is set to
undefined when the validation determines that the value is invalid. By
setting the allowInvalid property to true, the model will still be
updated even if the value is invalid.
Or you can just add something like this to your condition:
'has-error':... && (user.password_confirm && user.password && user.password_confirm !== user.password)
P.S. your code is a bit akward...

I opted for this solution, probably not the most elegant but it meets my use case:
userRegister.password_confirm.$dirty && userRegister.password_confirm.$viewValue !== userRegister.password.$viewValue
By using $viewValue I can compare the actual imput values of the two fields. If I use the ng-model values the user.password value but pass the regex validation before any value is passed to the ng-model. I want to provide feedback regarding the password/password_confirm without considering if the password is in itself valid.
So:
'password' is invalid
'password_confirm' does not match password and is also invalid
display message that they do not match.

Related

AngularJS - ng-pattern on a form failing for certain special symbols such as the dollar sign

I am writing an app with AngularJS 1.5. I am trying to write a feature where the user can verify their password in the app and I am using ng-messages to try to validate the form.
My from has 2 fields: password and confirm password.
The 2 validation conditions are: both passwords are required and the passwords must match.
The problem I have is the pattern match fails for a few special characters. It fails for the dollar sign but not all special characters. I need it to work for all characters.
Here is my JSFiddle: http://jsfiddle.net/aubz88/gm0obnqf/69/
A code snippet:
<div>
<label
class="item"
ng-class="{ 'has-error' : vm.verifyPassword.password.$invalid && (vm.verifyPassword.$submitted || vm.verifyPassword.$dirty) }">
<span class="input-label">Password</span>
<input
id="password"
type="password"
name="password"
ng-model="vm.data.password"
placeholder="password"
required>
</label>
</div>
The problem is this line in your JSFiddle, you pass vm.data.password (as a string) to ng-pattern.
ng-pattern="vm.data.password"
According to document of Arguments section of ngPattern https://docs.angularjs.org/api/ng/directive/ngPattern#ngPattern-arguments:
"AngularJS expression that must evaluate to a RegExp or a String parsable into a RegExp, or a RegExp literal."
So AngularJS parses your input into regular expression, that's why some symbols failed, for example $ (dollar sign), as $ is a reserved keyword in regular expression.

how to validate on form submit using AngularJS

I am very much new in angular js.I want to validate and post the form data using angular js on submit.I searched google but most of them was
disable the button on load ,after completing the form with valid data the button enable but I want to show error messages on form submit.
Here is My form snapshoot
I have tested with two text fields one is name and other is email but I want to proper messages for each fields e.g for email,phone no (valid format) and empty fields now I get only empty field message.
<span class="error-message"
ng-show="showMessage(frmReg.name)">
Please complete this field.</span>
var app=angular.module('regForm',[]);
app.controller('FormController',function($scope,$http){
$scope.frmRegField={};
$scope.frmSubmit=function(){
angular.forEach($scope.frmReg.$error.required, function(field) {
field.$setDirty();
});
// $http({
// method:"POST",
// url:"form_submit.php",
// data:$scope.frmRegField
// }).success(function(data){
// });
};
$scope.showMessage=function(input){
console.log(input.$$attr.name);
var show = input.$invalid && (input.$dirty || input.$touched);
return show;
};
});
You could use either class or state to do what you need
Input fields have the following states:
$untouched The field has not been touched yet
$touched The field has been touched
$pristine The field has not been modified yet
$dirty The field has been modified
$invalid The field content is not valid
$valid The field content is valid
They are all properties of the input field, and are either true or false.
Forms have the following states:
$pristine No fields have been modified yet
$dirty One or more have been modified
$invalid The form content is not valid
$valid The form content is valid
$submitted The form is submitted
The following classes are added to, or removed from, input fields:
ng-untouched The field has not been touched yet
ng-touched The field has been touched
ng-pristine The field has not been modified yet
ng-dirty The field has been modified
ng-valid The field content is valid
ng-invalid The field content is not valid
ng-valid-key One key for each validation. Example: ng-valid-required, useful when there are more than one thing that must be validated
ng-invalid-key Example: ng-invalid-required
The following classes are added to, or removed from, forms:
ng-pristine No fields has not been modified yet
ng-dirty One or more fields has been modified
ng-valid The form content is valid
ng-invalid The form content is not valid
ng-valid-key One key for each validation. Example: ng-valid-required, useful when there are more than one thing that must be validated
ng-invalid-key Example: ng-invalid-required
The classes are removed if the value they represent is false.
Give the form a name:
<form name="myForm">
And a name for the input to:
<input type="text" name="myName">
Then use ng-show/ng-if in your span:
<span class="error-message" ng-show="myForm.myName.$touched && myForm.myName.$invalid">
Please complete this field.
</span>
You can use ng-disabled to validate submit too:
<input type="submit" value="Submit" ng-disabled="myForm.$invalid">
Hope this helps. Good luck!

parsley().validate() always returns true for remote validation fields

I have a form with remote field validation using parsley.js:
<input type='text' name='username' id='username' required="true" data-parsley-trigger="focusout" data-parsley-remote="/ajax.php?UsernameExists" data-parsley-debounce="250"/>
Which works great, the field turns red when the username already exists, and green when the username is available.
Unfortunately upon clicking submit, I execute the following which always returns true, regardless of the username already exists or not:
form.parsley().isValid()
Instead of isValid I did use whenValidate() which returns a jQuery promise.
form.parsley().whenValidate().done(function(){
console.log('successfully validated');
});
required is treated differently than all other requirements. Check the doc for the {force: true} option.

how to make an angular input not be required when it's not shown

I have the following code
<div class="form-group" show-errors ng-show="contact.ContactType === 'LegallyMarriedSpouse' || contact.ContactType === 'Self'">
<label class="control-label">Social Security Number</label>
<input type="text" class="form-control" ng-model="contact.SSN" ui-mask="999-99-9999" name="SSN" maxlength="50" required />
</div>
I would have thought that Angular would have made sure that the hidden field was no longer required however that is not the case. although the user can't see it it's clearly still stopping the form from being submitted because I see the following error in the console.
An invalid form control with name='SSN' is not focusable.
So - the question is how do I handle this? If it's displayed I want it to be required if not obviously we can't try and force the user to fill out the values.
2 solutions:
use ng-if rather than ng-show to remove the input from the form rather than hiding it
instead of required, use ng-required="contact.ContactType === 'LegallyMarriedSpouse' || contact.ContactType === 'Self'" to make it required only when the condition showing the field is true. You should put that complex condition in a scope function though, to avoid duplicating it.
Note however that even if the form is invalid, it can still be submitted, unless you're explicitely preventing it by disabling its submit button when the form is invalid. I don't think the error you're seeing has anything to do with the form being invalid.
Also note that the second solution will only deal with the field being required. If the value inside the field is too long or doesn't match with the mask, the field will stay invalid. So you should probably use the first solution.

$scope.var giving undefined in angularjs

I am using angularjs to do client side validation on a textbox where I need input as alphanumeric chars only. If the textbox is left empty or non-alphanumeric char is entered, the submitform sends 'false' to JS which is desired but the problem is it doesn't pass the non-alphnumeric char itself (in the scope).
JSP file:
<form name="addressForm" method="post"
ng-submit="submitform(addressForm.$valid)" novalidate>
..
<input ng-model="address" type="text"
**ng-pattern**="/^[a-zA-Z0-9 ]*$/" required="true"/>
JS file:
$scope.submitform= function(isValid){
var inputAddr = $scope.address;
alert(inputAddr); //coming as undefined
...
Now when I input an alphanumeric character in input box 'address' in jsp it gives me undefined on alerting it in JS (probably because of pattern which filters the char being non-alphanumeric). If I remove ng-pattern, it passes the submitForm passes 'true' as if every input is "as expected". The reason I want to access $scope.address is to check and value and display different error message for "empty" and a "non-alphanumeric" validation.
Any help is appreciated !
When the model is not valid, the value is not assigned to the model. If you want to see what the user has typed, you need to check $viewValue:
You must to add name attribute to input, so change your input html to:
<input ng-model="address" type="text" name="address"
ng-pattern="/^[a-zA-Z0-9 ]*$/" required="true"/>
And change your submit function to
$scope.submitform = function(isValid) {
console.log($scope.addressForm.address.$viewValue);
}
It sounds like you just need to know what the validation error is.
You can check the $error property the FormController (addressForm in your case) to see what validations passed or failed.
For example, if the input is empty, then the "required" validation will have failed and addressForm.$error.required will be an Array containing the inputs that failed this validation.
If the "required" validation succeeded, then addressForm.$error.required will just be false.
You can use this in angular expressions quite easily:
<p ng-show="addressForm.$error.required">This field is required.</p>
Or you can access the form through the $scope object that is associated with the view:
if ($scope.addressForm.$error.required) {
// required validation failed
}
Check out the documentation for FormController and ngModelController.

Resources