AngularJS comparing two input values doesn't work as expected - javascript

I am trying to compare two password values using AngularJS. I have the submit button disabled until all the fields are valid. However, it is not working like it is supposed to. As soon as I enter the email and the first password, the submit button becomes enabled. But if I type something else in the second password field, then the submit button becomes disabled again. How do I do the validation even when nothing is entered in the second password field?
Here, is my form.
<form ng-submit="submit()" name="register" class="form-signin" novalidate>
<h1 class="form-signin-heading text-muted">
Register
</h1>
<input name="email" ng-model="email" type="email" class="form-control" placeholder="Email address" required>
<p class="help-block" ng-show="register.email.$dirty && register.email.$invalid">Please enter a valid email</p>
<input name="password" ng-model="password" type="password"class="form-control" placeholder="Password" required>
<input name="password_confirm" ng-model="password_confirm" type="password" class="form-control" placeholder="Confirm Password" validate-equals='password'>
<p class="help-block" ng-show="register.password_confirm.$dirty && register.password_confirm.$invalid">The passwords do not match</p>
<button ng-disabled="register.$invalid" class="btn btn-lg btn-primary btn-block" type="submit">Submit</button>
And here is the Javascript file(validateEquals.js)
'use strict';
angular.module('jwtApp').directive('validateEquals', function () {
return {
require: 'ngModel',
link: function(scope, element, attrs, ngModelCtrl) {
function validateEqual(value) {
var valid = (value === scope.$eval(attrs.validateEquals));
ngModelCtrl.$setValidity('equal', valid);
return valid ? value : undefined;
}
ngModelCtrl.$parsers.push(validateEqual);
ngModelCtrl.$formatters.push(validateEqual);
scope.$watch(attrs.validateEquals, function() {
ngModelCtrl.$setViewValue(ngModelCtrl.$viewValue);
});
}
};
});

If I can make a suggestion - do this:
<button ng-disabled="register.$invalid || password != password_confirm" class="btn btn-lg btn-primary btn-block" type="submit">Submit</button>
And not use the validateEqual implementation in your directive. Here's a fiddle: http://jsfiddle.net/jochenvanwylick/U3pVM/13972/ with your code and the fix. I wouldn't make it into a directive, nor would I try to hook into the $parsers and $formatters for the element.

try this
.directive('validateEquals', [function () {
return {
require: 'ngModel',
link: function (scope, elem, attrs, ctrl) {
var firstPassword = '#' + attrs.validateEquals;
elem.add(firstPassword).on('keyup', function () {
scope.$apply(function () {
var v = elem.val()===$(firstPassword).val();
ctrl.$setValidity('inputmatch', v);
});
});
}
}
on html you can check like this
<input type="password" id="input1" name="input1" ng-model="input1" ng-required/>
<input type="password" id="input2" name="input2" ng-model="input2" ng-required validate-equals="input1"/>
hope will help this solution :)
EDIT
can show error message like this
<div ng-show="myForm.$error">
<span ng-show="myForm.input2.$error.inputmatch">
Passwords don't match.
</span>
</div>

Related

How to compare values in Angularjs?

I'm a newbie to angular, so I need a help.
In html, I wrote the following
<div class="form-group">
<input type="email" name="Email" id="LoginEmail class="form-control" placeholder="Email Address" required>
</div>
<div class="form-group">
<input type="password" name="password" id="LoginPassword" class="form-control" placeholder="Password" required>
</div>
In angular, I write the following code
angular
.module("LoginForm", [])
.controller("processingLoginForm", ["$scope", function ($scope) {
$scope.userinfo = [
{name : "User1",
account : "user1#whatever.com",
city: "XYZ",
password: "Angular#2017"}
];
}]);
I need to compare the value of input box with the value of the script and show a message if it's not correct, so how can I do that?
Firstly you need to assign model to your template scope. Use ng-model for this purpose. Then you need a form to submit and trigger a function to check if user input matches to the desired values.
Add ng-model and wrap your inputs with a form tag:
<form ng-submit="login()">
<div class="form-group">
<input ng-model="email" type="email" name="Email" id="LoginEmail" class="form-control" placeholder="Email Address" required>
</div>
<div class="form-group">
<input ng-model="password" type="password" name="password" id="LoginPassword" class="form-control" placeholder="Password" required>
</div>
<button type="submit">Login</button>
</form>
Check if user input is valid in Controller:
$scope.login = function() {
const isUserValid = $scope.email === $scope.userinfo[0].account && $scope.password === $scope.userinfo[0].password;
if(isUserValid) {
alert("Logged In Successfully");
}else {
alert("Email or password incorrect. Try again.")
}
}
Here's a working example of the above code.
In your input elements you miss the ng-model attribute. It is used to bind the values with your scope variables.
<input type="email" ... ng-model="email" ...>
<input type="password" ... ng-model="password" ...>
And in your controller you can write
if($scope.email == $scope.userinfo[0].account && $scope.password == $scope.userinfo[0].password){
//Login ok
}else{
//Login failed
}
Assuming there is a form element somewhere above
Add ng-submit to it
<form ng-submit="submit()">
Add ng-model to the form elements.
I have added state.email and state.password
<div class="form-group">
<input ng-model="state.email" type="email" name="Email" id="LoginEmail" class="form-control" placeholder="Email Address" required>
</div>
<div class="form-group">
<input ng-model="state.password" type="password" name="password" id="LoginPassword" class="form-control" placeholder="Password" required>
</div>
Compare the binding values to the values in $scope.userinfo
angular
.module("LoginForm", [])
.controller("processingLoginForm", ["$scope", function ($scope) {
$scope.userinfo = [{
name : "User1",
account : "user1#whatever.com",
city: "XYZ",
password: "Angular#2017"
}];
// when you submit the form, this function will be called
$scope.submit = function (e) {
e.preventDefault();
if ($scope.state.email !== $scope.userinfo[0].account || $scope.state.password !== $scope.userinfo[0].password) {
// did not match
} else {
// matched
}
}
}]);

Button remains active when no values are entered in textfield

I'm working on a page where i want to disable the submit button till all values are entered in the textbox, but when the page loads the submit button is already active
.directive('passwordVerify', function() {
return {
restrict: 'A',
require: '?ngModel',
link: function(scope, elem, attrs, ngModel) {
scope.$watch(attrs.ngModel, function() {
if (scope.confirm_password === scope.user_password) {
scope.pw.confirm_password.$setValidity('passwordVerify', true);
scope.pw.user_password.$setValidity('passwordVerify', true);
} else if (scope.confirm_password !== scope.user_password) {
scope.pw.confirm_password.$setValidity('passwordVerify', false);
scope.pw.user_password.$setValidity('passwordVerify', false);
}
});
}
};
})
HTML
<div class="list">
<form id="create" name="pw" method="post">
<label class="item item-input item-stacked-label">
<span class="input-label">Username</span>
<input type="text" placeholder="kojobaah" ng-model="username" required>
</label>
<label for="password">New Password
<input type="password" name="user_password" ng-model="user_password" ng-required="confirm_password && !user-password" password-verify="confirm_pasword">
<p ng-show="pw.user_password.$error.passwordVerify">Passwords do not match</p>
<p ng-show="pw.user_password.$error.required">This field is required</p>
</label>
</p>
<p>
<label for="password">Confirm Password
<input type="password" name="confirm_password" ng-model="confirm_password" ng-required="user_password && !confirm_password" password-verify="user_password">
<p ng-show="pw.confirm_password.$error.passwordVerify">Passwords do not match</p>
<p ng-show="pw.confirm_password.$error.required">This field is required</p>
</label>
<br />
<p align="center"><button ng-disabled="create.$invalid" class="button button-balanced" ng-click="register()">Create Account</button></p>
</form>
</div>
In:
<button ng-disabled="pw.$invalid" class="button button-balanced"
ng-click="register()">Create Account</button>
create.$invalid change to pw.$invalid
Use name form and not id
not sure where it would go exactly, but here's what I found, it disables the submit button:
function myFunction() {
document.getElementById("mySubmit").disabled = true;
It might have to be "tweaked" to work with your code to be active once all the values are entered. Not sure if this helps

How to change validation of password with another input in AngularJS?

I have 3 input like this:
<div class="form-group">
<label for="username">Username</label>
<input type="text"
ng-model="formModel.username"
class="form-control"
id="username"
name="username"
required>
<span class="help-block"
ng-show="myForm.username.$error.required && myForm.username.$dirty">
Required
</span>
</div>
<div class="form-group">
<label for="password">Password</label>
<input type="password"
class="form-control"
id="password"
name="password"
ng-model="formModel.password"
required
valid-my-password>
<span class="help-block"
ng-show="myForm.password.$error.required && myForm.password.$dirty">
Required
</span>
<span class="help-block"
ng-show="!myForm.password.$error.required &&
myForm.password.$error.sameAs && myForm.password.$dirty || myForm.username.$dirty">
Username and password are similar
</span>
</div>
<div class="form-group">
<label for="password_c">Approve password</label>
<input type="password"
class="form-control"
id="password_c"
name="password_c"
ng-model="formModel.password_c"
required
valid-password-c />
<span class="help-block"
ng-show="myForm.password_c.$error.required && myForm.password_c.$dirty">
You need to approve the password
</span>
<span class="help-block"
ng-show="!myForm.password_c.$error.required && myForm.password_c.$error.noMatch &&
myForm.password.$dirty">
Passwords don't match
</span>
</div>
And the validation works great. but:
1. if the password are similar to the username, and I try to change the username, the alert dosn't dissaper.
2. if the password and the confirm password input are filled and the validation is okay, and i'm trying to change the password, the alert of "Passwords don't match" doesn't show.
jsFiddle
Just change your error validations with snippets below
<span class="help-block" ng-show="!myForm.password.$error.required &&
myForm.password.$error.sameAs && myForm.password.$dirty && formModel.password==formModel.username">
Username and password are similar
</span>
<span class="help-block" ng-show="!myForm.password_c.$error.required && myForm.password_c.$error.noMatch &&
myForm.password.$dirty && formModel.password_c!=formModel.password">
Passwords don't match
</span>
Here is the updated link of your fiddle
http://jsfiddle.net/vz215k94/
I found my answer. I add another directive called "validMyUsername" and i call him from the username input. In this directive i change the password validation.
and for the confirm password I change in the password directive the validation.
like this:
The username input directive:
...
directive('validMyUsername', function () {
return {
require: 'ngModel',
link: function (scope, elm, attrs, ctrl) {
ctrl.$parsers.unshift(function (viewValue, $scope) {
var sameAs = viewValue != scope.myForm.password.$viewValue
scope.myForm.password.$setValidity('sameAs',sameAs);
ctrl.$setValidity('sameAs',sameAs);
return viewValue;
})
}
}
The password directive:
...
directive('validMyPassword', function () {
return {
require: 'ngModel',
link: function (scope, elm, attrs, ctrl) {
ctrl.$parsers.unshift(function (viewValue, $scope) {
var sameAs = viewValue != scope.myForm.username.$viewValue
var noMatch = viewValue != scope.myForm.password_c.$viewValue
scope.myForm.password_c.$setValidity('noMatch',!noMatch);
ctrl.$setValidity('sameAs', sameAs)
return viewValue;
})
}
}
})
Here is the full example: jsFiddle

Using AngularJS ngModel and Form Validation to $watch two elements and test if they are equal whenever either input changes

What I am trying to do is create a directive which compares two password inputs and triggers invalid if either changes. I have found a few examples and have tried a few and have combined a few in my own attempts. However, I have only been able to toggle the validity with $setValidity when the confirm password field changes. When you change the password field it doesn't trigger the invalidity of the comparison.
Here's my directive:
app.directive("passwordVerify", function() {
return {
require: "ngModel",
scope: {
passwordVerify: '=',
},
link: function(scope, element, attrs, ctrl) {
scope.$watch(function() {
var combined;
if (scope.passwordVerify || ctrl.$viewValue) {
combined = scope.passwordVerify + '_' + scope.$view;
}
return combined;
}, function(value) {
if (value) {
ctrl.$parsers.unshift(function(viewValue) {
var origin = scope.passwordVerify;
if (origin !== viewValue) {
ctrl.$setValidity("pwd", false);
return undefined;
} else {
ctrl.$setValidity("pwd", true);
return viewValue;
}
});
}
});
}
};
});
Here's the directive in action:
<input id="user_password" type="password" name='user_password' placeholder="password" value='' required ng-model="user.user_password">
<p class="help-text">Required</p>
<div class="help-block" ng-messages="add_user_form.user_password.$error" ng-show="add_user_form.user_password.$touched">
<div ng-messages-include="/app/views/messages.html" ></div>
<input id="confirm_password" ng-model="user.confirm_password" name="confirm_password" type="password" placeholder="confirm password" name="user_confirm_password" required password-verify="user.user_password">
<p class="help-text">Enter matching password</p>
<div class="help-block" ng-messages="add_user_form.confirm_password.$error" ng-show="add_user_form.confirm_password.$touched">
<div ng-messages-include="/app/views/messages.html" ></div>
With this code I can verify that the passwords match when I change the value of the confirm password field, however when you change the value of the password field it doesn't revalidate the input. I'm pretty sure there is a successful way to add $watch to two elements or to use $watchgroup to do this. I just can't figure it out. I know there are a lot of questions on this topic but all I've tried have only gotten me to this point.
I'm using Angular 1.5.7 btw...
Here's a version working bi-directionally:
(function() {
"use strict";
angular.module('app', ['ngMessages'])
.controller('mainCtrl', function($scope) {
})
.directive('passwordVerify', function() {
return {
restrict: 'A', // only activate on element attribute
require: '?ngModel', // get a hold of NgModelController
link: function(scope, elem, attrs, ngModel) {
if (!ngModel) return; // do nothing if no ng-model
// watch own value and re-validate on change
scope.$watch(attrs.ngModel, function() {
validate();
});
// observe the other value and re-validate on change
attrs.$observe('passwordVerify', function(val) {
validate();
});
var validate = function() {
// values
var val1 = ngModel.$viewValue;
var val2 = attrs.passwordVerify;
// set validity
ngModel.$setValidity('passwordVerify', !val1 || !val2 || val1 === val2);
};
}
}
})
})();
<html ng-app="app">
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.7/angular.min.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.6/css/bootstrap.min.css" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.6/js/bootstrap.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular-messages/1.5.7/angular-messages.min.js"></script>
</head>
<body ng-controller="mainCtrl">
<form name="add_user_form">
<div class="col-md-12">
<div class="form-group" ng-class="{ 'has-error' : add_user_form.user_password.$touched && add_user_form.user_password.$invalid }">
<p class="help-text">Enter password</p>
<input type="password" class="form-control" id="user_password" name="user_password" placeholder="password" required ng-model="user.user_password" password-verify="{{user.confirm_password}}">
<div class="help-block" ng-messages="add_user_form.user_password.$error" ng-show="add_user_form.user_password.$touched">
<p ng-message="required">This field is required</p>
<p ng-message="minlength">This field is too short</p>
<p ng-message="maxlength">This field is too long</p>
<p ng-message="required">This field is required</p>
</div>
</div>
<div class="form-group" ng-class="{ 'has-error' : add_user_form.confirm_password.$touched && add_user_form.confirm_password.$invalid }">
<p class="help-text">Enter matching password</p>
<input class="form-control" id="confirm_password" ng-model="user.confirm_password" name="confirm_password" type="password" placeholder="confirm password" required password-verify="{{user.user_password}}">
<div class="help-block" ng-messages="add_user_form.confirm_password.$error" ng-show="add_user_form.confirm_password.$touched">
<p ng-message="required">This field is required</p>
<p ng-message="minlength">This field is too short</p>
<p ng-message="maxlength">This field is too long</p>
<p ng-message="required">This field is required</p>
<p ng-message="passwordVerify">No match!</p>
</div>
</div>
</div>
</form>
</body>
</html>
I hope it helps.

Angularjs : display message

i'm try to display message when password don't match but not not showing any idea ?i'm try to display message when password don't match but not not showing any idea ?
directive:
angular.module('crud')
.directive('equal', function () {
return {
require: 'ngModel',
scope: {
equal: '='
},
link: function(scope, elem, attrs, ctrl) {
ctrl.$validators.equal = function(modelValue, viewValue) {
return modelValue === scope.equal;
};
scope.$watch('equal', function(newVal, oldVal) {
ctrl.$validate();
});
}
};
});
html
<form name="userForm" ng-submit="signup()" class="form-horizontal" role="form" >
<input type="password" class="form-control ng-invalid submitted" id="password" name="password" ng-model="password" ng-minlength="8" ng-maxlength="20" required />
<input type="password" equal="password" class="form-control ng-invalid submitted" id="confirmPassword" name="confirmPassword" ng-model="confirmPassword" required />
<span ng-show="userForm.password.$error.equal && userForm.password.$dirty">Passwords don't match.</span>
</form>
Everything is fine with one exception, you should add equal directive on password input, because you are displaying errors for password, so you should validate password. Other than that it is ok. Although you might consider using ng-messages for displaying errors.
angular.module('crud', ['ngMessages']);
angular.module('crud')
.directive('equal', function () {
return {
require: 'ngModel',
scope: {
equal: '='
},
link: function(scope, elem, attrs, ctrl) {
ctrl.$validators.equal = function(modelValue, viewValue) {
return modelValue === scope.equal;
};
scope.$watch('equal', function(newVal, oldVal) {
ctrl.$validate();
});
}
};
});
.valid {
border: 1px solid green;
}
.invalid {
border: 1px solid red;
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.5/angular.js"></script>
<script src="https://code.angularjs.org/1.5.5/angular-messages.js"></script>
<div ng-app="crud">
<form name="userForm" class="form-horizontal" role="form" >
<input type="password" class="form-control ng-invalid submitted" id="password" name="password" equal="confirmPassword" ng-model="password" ng-minlength="8" ng-maxlength="20" ng-class="{'valid': userForm.password.$valid || !userForm.password.$dirty, 'invalid': userForm.password.$invalid && userForm.password.$dirty}" required />
<input type="password" class="form-control submitted" id="confirmPassword" name="confirmPassword" ng-model="confirmPassword" required />
<div ng-messages="userForm.password.$error" ng-show="userForm.password.$dirty" role="alert">
<div ng-message="required">Please enter a value for this field.</div>
<div ng-message="equal">Passwords don't match.</div>
</div>
</form>
</div>

Categories