AngularJS ngDisabled isn't activated as it should be - angularjs

I have a code that should disable a button when : registerForm.$invalid || form.password != form.passwordBis, which should mean : "Disable the button if the form isn't valid OR if the '$scope.form.password' variable isn't equal to '$scope.form.passwordBis'.", isn't it?
So here I have a code that activate the button if the two passwords matches. Which shouldn't happen, because the first condition is still wrong !
HTML :
<div ng-app="app" ng-controller="formCtrl">
<form name="registerForm">
<div class="header">
<h2>Create your account</h2>
</div>
<div class="form-group">
<div class="title">First Name</div>
<input type="text" name="firstName" ng-required class="form-control" ng-class="{empty:form.firstName.length==0}" ng-model="form.firstName" required></input>
</div>
<div class="form-group">
<div class="title">Last Name</div>
<input type="text" name="lastName" ng-required class="form-control" ng-class="{empty:form.lastName.length==0}" ng-model="form.lastName" required></input>
</div>
<div class="form-group">
<div class="title">Email</div>
<input type="email" name="email" ng-required class="form-control" ng-class="{empty:form.email.length==0}" ng-model="form.email" required></input>
</div>
<div class="form-group">
<div class="title">Password</div>
<input type="password" name="password" class="form-control" ng-class="{empty:form.password.length==0}" ng-model="form.password" required></input>
<input type="password" name="passwordBis" class="form-control" ng-class="{empty:form.passwordBis.length==0}" ng-model="form.passwordBis" minlength="6" required></input>
</div>
<div ng-if="form.password != form.passwordBis" class="error">Passwords doesn't match.</div>
<div class="form-group">
<button class="btn btn-success" ng-click="register()" ng-disabled="registerForm.$invalid || form.password != form.passwordBis">Register</button><br/>
</div>
</form>
</div>
JS :
var app = angular.module("app", []);
app.controller("formCtrl", function($scope) {
$scope.form = {
firstName: "",
lastName: "",
email: "",
password: "",
passwordBis: ""
};
});
And you can test it : JSFiddle
What am I missing ?

Remove ng-required attributes from your form elements.
For form elements you should use either ng-required or required, but not both at the same time. ng-required expects an expression that needs to evaluate to true in order to mark a form element as required, whereas required doesn't need any value. See https://stackoverflow.com/a/16648851/1237995 for more detailed explanation.

Related

How to display error message when passwords doesn't match in Angularjs?

I'm new at Angularjs and my question is how to display an error message when the password doesn't match with confirm password?
Can someone help me, this is not very difficult but I'm still learning to programme.
Thanks to everyone!
I have html code:
<form ng-submit="saveItem(userForm.$valid)" name="userForm">
<div class="row">
<div class="col-sm-6">
<div class="form-group">
<label for="database_address">User</label>
<input type="text" class="form-control" required ng-model="activeItem.username" placeholder="Потребителско Име..." />
</div>
<div class="form-group">
<label for="password">Password</label>
<input type="text" class="form-control" id="password" ng-model="activeItem.passwordString" />
</div>
<div class="form-group">
<label for="password">Confirm Password</label>
<input type="text" class="form-control" id="password" ng-model="activeItem.passwordConfirm" />
</div>
<p ng-show="(userForm.passwordConfirm != '') && (userForm.password != userForm.passwordConfirm)">Passwords don't match</p>
</div>
<div class="col-sm-6">
<div class="form-group">
<label for="username">Operator</label>
<input type="text" class="form-control" required id="username" ng-model="activeItem.name" />
</div>
</div>
</div>
<button class="btn btn-primary" ng-disabled="userForm.$invalid" type="submit">Save</button>
<!--<button class="btn btn-primary" ng-disabled="userForm.$invalid" type="submit">Добавяне на нов</button>-->
</form>
And angular function:
$scope.saveItem = function(){
console.log($scope.activeItem);
//delete $scope.activeItem.hash_method
var objectToSave = {
username: $scope.activeItem.username,
//password: $scope.activeItem.password,
name: $scope.activeItem.name,
id: $scope.activeItem.id
};
if($scope.activeItem.passwordString != ''){
if($scope.activeItem.passwordString == $scope.activeItem.passwordConfirm){
objectToSave.password = $scope.activeItem.passwordString;
} else {
console.log('Confirm password error');
}
}
You'll want to keep different Id's for the two password fields, also take a look at your model bindings:
<input type="text" class="form-control" id="password" ng-model="activeItem.passwordString" />
<input type="text" class="form-control" id="passwordConfirm" ng-model="activeItem.passwordConfirm" />
You can just reference the items that are bound with ng-model within an ng-if/ng-show, and then you shouldn't need any custom logic on the back-end.
<p ng-show="(activeItem.passwordString && activeItem.passwordConfirm) && activeItem.passwordString
!== activeItem.passwordConfirm ">Passwords don't match</p>
Also, you'll probably want to use '!==' over '!=' since you're just comparing two strings, as it's more strict of a comparison.
Edit: one thing to note, with this direction you'll still probably want to do error checking in the save function, but this should handle displaying the error message without any issues.
Remember the operator for 'not equal' is "!==", with that you will be able to make it!

NgFormModel NgControl read value

I have a form where I have already values in the input text field. After the submit button (changes) the unchanged input field returns a empty string in the json object.
//the component
this.builder = fb;
this.EditUserForm = this.builder.group({
firstName: ["", Validators.required],
lastName: ["", Validators.required],
});
<form [ngFormModel]="EditUserForm" (submit)="saveChanges($event)">
<div class="col-xs-2">
<label for="firstname">First Name</label>
<input class="form-control" id="firstname" ngControl="firstName" type="name" required value={{person.firstName}}>
</div>
<div class="col-xs-2" >
<label for="lastname">Last Name</label>
<input class="form-control" id="lastname" ngControl="lastName" type="name" required value={{person.lastName}}>
</div>
<div class="container">
<button type="submit" class="btn btn-primary">Save Changes</button>
</div>
</form>
As you can see I have already values in the input. But the ngControl does not take this. Only when I put a change value in the input text field. It shows the value person.firstname but does not read it in ngControl
Other answer would be (with your setup),
You can make use of [(ngModel)] directive which actally binds your value to input control and updates ngCtrl status.
<input ... [(ngModel)]="person.firstName" #firstName="ngForm" ...>
Look at here working example of the same,
https://plnkr.co/edit/hvAG3lLpfP80U9hMKAEA?p=preview
you have to use [ngFormControl] for binding the controls in the template.
//the component
this.builder = fb;
this.EditUserForm = this.builder.group({
firstName: ["", Validators.required],
lastName: ["", Validators.required],
});
<form [ngFormModel]="EditUserForm" (submit)="saveChanges(EditUserForm.values)">
<div class="col-xs-2">
<label for="firstname">First Name</label>
<input class="form-control" id="firstname" [ngFormControl]="EditUserForm.controls['firstname']" type="name" required value={{person.firstName}}>
</div>
<div class="col-xs-2" >
<label for="lastname">Last Name</label>
<input class="form-control" id="lastname" [ngFormControl]="EditUserForm.controls['lastname']" type="name" required value={{person.lastName}}>
</div>
<div class="container">
<button type="submit" class="btn btn-primary">Save Changes</button>
</div>
</form>

Password don't match angularJs

I don't seem to understand why ng-show is failing to display this validation when the passwords don't match. What am I missing?
<form name="myForm">
<div class="form-group">
<input ng-required="true" name="username" ng-minlength="3" ng-maxlength="10" ng-model="model.user.username" type="text" class="form-control" id="user-name" placeholder="Username">
<p class="errorValidationText" ng-show="myForm.username.$invalid && myForm.username.$touched">Please pick a username between 3 - 10 characters.</p>
</div>
<div class="form-group">
<input ng-required="true" name="password" ng-minlength="4" ng-model="model.user.password" type="password" class="form-control" id="password" placeholder="Password">
<p class="errorValidationText" ng-show="myForm.password.$invalid && myForm.password.$touched">Password should contain atleast 4 characters.</p>
</div>
<div class="form-group">
<input ng-required="true" name="verifyPassword" ng-minlength="4" ng-model="model.user.verifyPassword" type="password" class="form-control" id="verify-password" placeholder="Verify Password">
<p class="errorValidationText" ng-show="(myForm.verifyPassword.value != '') && (myForm.password.value != myForm.verifypassword.value)">Passwords don't match.</p>
</div>
<button ng-disabled="myForm.username.$invalid || myForm.password.$invalid || myForm.verifyPassword" ng-click="model.register(model.user)" class="btn btn-success btn-block">Register</button>
</form>
Thanks!!
I've reffered the other solutions, none of the existing questions are similar to what I am doing.
The myForm object doesn't have the input values, you can see that with {{myForm}}. Use the value from ngModel instead:
<p ng-show="(user.model.verifyPassword != '') && (user.model.password != user.model.verifyPassword)">Passwords don't match</p>
Also notice that if your input is not valid, ngModel won't set the value: user.model.verifyPassword != '' is going to be always true, since you set ng-minlength=4.
Another tip: ng attributes make sense only if you evaluate a scope variable, ng-required="true" is the same as required="required".
myForm.verifyPassword.value casing is different in your statement myForm.verifypassword.value
I made up an example as I didn't have your code
var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope) {
$scope.myForm = {
password: '',
verifyPassword: ''
};
$scope.submit = function() {
console.log('success');
};
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="myApp" ng-controller="myCtrl">
Password:
<input type="password" ng-model="myForm.password">
<br>Verify Password:
<input type="password" ng-model="myForm.verifyPassword">
<br>
<p ng-show="(myForm.verifyPassword != '') && (myForm.password != myForm.verifyPassword)">Passwords don't match</p>
<button>Submit</button>
</div>

$scope.formName.fieldName.$setValidity is not working

I would like to set invalid with angular when firstname is equals to lastname and change the color using styles to red.
http://jsbin.com/japir/2
function RegoController($scope) {
$scope.app = {
firstName: "Saroj"
};
$scope.$watch("app.lastName", function(newVal, oldVal) {
if (!!$scope.app.lastName && !!newVal)
if (angular.lowercase($scope.app.firstName) === angular.lowercase(newVal)) {
debugger;
$scope.form.inputLastName.$setValidity("sameName", false);
}
});
}
<body ng-app>
<div class="container" ng-controller="RegoController">
<div class="col-lg-4">
<form name="form">
<div class="form-group">
<label for="inputFirstName">First Name</label>
<input id="inputFirstName" class="form-control" type="text" ng-model="app.firstName" placeholder="Enter your firstname" required ng-minlength="3" ng-maxlength="20" />
</div>
<div class="form-group">
<label for="inputLastName">Last Name</label>
<input id="inputLastName" class="form-control" type="text" ng-model="app.lastName" placeholder="Enter your last name" required ng-minlength="3" ng-maxlength="20" />
</div>
<div class="form-group">
<label for="inputEmail">Email</label>
<input id="inputEmail" class="form-control" type="email" ng-model="app.email" placeholder="Enter your email" required />
</div>
<div class="form-group">
<input type="submit" class="btn btn-primary" value="Save" />
</div>
</form>
{{app}}
</div>
</div>
</body>
The problem is that you are trying to select a form input that has no name; thus making it unable to find the field you are trying to invalidate. Here is a working example:
JSBIN: http://jsbin.com/yozanado/1/
Input field with name:
<input id="inputLastName" name="lastName" class="form-control" type="text" ng-model="app.lastName" placeholder="Enter your last name" required ng-minlength="3" ng-maxlength="20" />
Javascript:
$scope.form.lastName.$setValidity("sameName", false);
AngularJS form validation relies on the name of the form and the name of the fields to find the validation models on scope.
For example, if your HTML is:
<form name="form">
<input name="firstName" ng-model="firstName" />
</form>
You will be able to access the validation $error property on scope using the name attributes:
$scope.form.firstName.$error.sameName
To fix the issues you're having, add a name attribute to your input fields.
JSBin Demo

How to display form errors just when input are invalid and dirty?

I have working with AngularJS. I have the following form :
<html lang="en" ng-app="app">
...
<div ng-controller="RegisterController">
<h3>Register</h3>
<form name="registerForm" class="form-horizontal panel-body" novalidate="novalidate">
<form name="registerForm" class="form-horizontal panel-body" novalidate="novalidate">
<div class="form-group">
<label name="firstname" class="col-md-2 control-label">First Name</label>
<div class="col-md-4">
<input type="text" class="form-control" name="firstname" ng-model="user.firstname" placeholder="First Name" required>
</div>
</div>
<div class="form-group">
<label name="lastname" class="col-md-2 control-label">Last Name</label>
<div class="col-md-4">
<input type="text" class="form-control" name="lastname" ng-model="user.lastname" placeholder="Last Name" required>
</div>
</div>
<div class="form-group">
<label name="email" class="col-md-2 control-label">Your email</label>
<div class="col-md-4">
<input type="email" class="form-control" name="email" ng-model="user.email" placeholder="Email Address" required>
</div>
<div class="col-md-2">
<span ng-show="showError(userInfoForm.email, 'email')" ...>
You must enter a valid email
</span>
<span ng-show="showError(userInfoForm.email, 'required')" ...>
This field is required
</span>
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-6">
<button class="btn btn-sm btn-primary" ng-disabled="!canRegister()" ng-click="submit()">Register</button>
</div>
</div>
I have also app.js file which contains configuration and controller code, i just paste the controller code:
app.controller('RegisterController', function($scope) {
$scope.getCssClasses = function(ngModelContoller) {
return {
error: ngModelContoller.$invalid && ngModelContoller.$dirty,
success: ngModelContoller.$valid && ngModelContoller.$dirty
};
};
$scope.showError = function(ngModelController, error) {
return ngModelController.$error[error];
};
$scope.canRegister = function() {
return $scope.registerForm.$dirty &&
$scope.registerForm.$valid;
};
});
My problem is that when i load the register page ( the page which contains the form), i have the two errors are printed :
You must enter a valid email This field is required
I am wondering how to do print the error when the input is dirty and invalid and desapear when the input text is valid.
Thansk for your help
Set class "validate" on each input class, and add style.css, like:
.validate.ng-dirty.ng-invalid {
border: 2px solid red;
}
.validate.ng-dirty.ng-valid {
border: 2px solid green;
}
Here is one way (of many) to validate forms http://plnkr.co/edit/u0Wr0dza8lGnVrgwrUEa
$error is the object of errors where the key is the field validation name and value is the actual error message
<input type="email" name="emailName" ng-model="email" required>
for this example myForm.emailName.$error.email = true if email is not matched with format.
myForm.emailName.$error.required = true if you haven't added anyhting in input field
you can check valid or not of the field directly by using myForm.emailName.$valid but
the problem in your case is they want to show the user what is the error by having two cases. so they entered into $error object to check for the error is required email or invalid email
1.Email is required.
2.Invalid email address.
so they used $error object.
this is how myForm.emailName looks:
{"$viewValue":"ss","$validators":{},"$asyncValidators":{},"$parsers":[],"$formatters":[null],"$viewChangeListeners":[],"$untouched":false,"$touched":true,"$pristine":false,"$dirty":true,"$valid":false,"$invalid":true,"$error":{"email":true},"$name":"emailName","$options":null}
check this out

Resources