Show ng-message content only when validation fails in Angularjs - javascript

I have found some custom code online for simple login form:
<div class="col-md-6 col-md-offset-3">
<h2>Login</h2>
<form name="form" ng-submit="form.$valid && vm.login()" novalidate>
<div class="form-group" ng-class="{ 'has-error': form.$submitted && form.username.$invalid }">
<label for="username">Username</label>
<input type="text" name="username" class="form-control" ng-model="vm.username" required />
<div ng-messages="form.$submitted && form.username.$error" class="help-block">
<div ng-message="required">Username is required</div>
</div>
</div>
<div class="form-group" ng-class="{ 'has-error': form.$submitted && form.password.$invalid }">
<label for="password">Password</label>
<input type="password" name="password" class="form-control" ng-model="vm.password" required />
<div ng-messages="form.$submitted && form.password.$error" class="help-block">
<div ng-message="required">Password is required</div>
</div>
</div>
<div class="form-group">
<button class="btn btn-primary">Login</button>
</div>
<div ng-if="vm.error" class="alert alert-danger">{{vm.error}}</div>
</form>
</div>
Currently, ng-messages with content: 'Username is required' and 'Password is required' are always visible.
Is there any chance I can change this code in a way I see that messages only when authentication fails?
Or in other words can I hide them in HTML, because I guess I have to show them through angular code.

Set an ng-if on your div, checking for the errors:
ng-if="form.password.$error"
ng-if="form.username.$error"
This will ensure that the div only shows if an error in your form exists, specific to those elements.

You can use FormController.$dirty or FormController.$pristine
By Angular Docs:
$pristine: True if user has not interacted with the form yet.
$dirty: True if user has already interacted with the form.
<div ng-if="form.$dirty && vm.error" class="alert alert-danger">{{vm.error}}</div>

Related

Javascript, validation of password with bootstrap

i'm trying to learn Javascript and some basic HTML with bootstrap v5.
I created a Sign-in form and now i'm try to do some validation for the required field.
I follow the Bootstrap documentations and i managed to get validation for all my input field except for the password, i want to verify if the password are the same or if they are empty field...but i'm stuck.. not familiar with javascript.
my attempt in javascript:
let forms = document.querySelectorAll(".needs-validations");
let pass1 = document.getElementById("password1");
let pass2 = document.getElementById("password2");
Array.prototype.slice.call(forms).forEach( function (form){
form.addEventListener("submit",function (ev) {
// test password check....
if (pass1.value !== pass2.value || pass1.value === "" || pass2.value === "" ){
pass1.className = 'form-control is-invalid'
pass2.className = 'form-control is-invalid'
}
if (!form.checkValidity()){
ev.preventDefault()
ev.stopPropagation()
}
form.classList.add("was-validated")
})
})
but here the result:
As you can see password is always valid and i don't understand why.
my html:
<body class="body">
<div class="center">
<h4 class="title">Sign Up New User</h4>
<form name="signin-form" method="post" class="needs-validations" novalidate id="forms">
<div class="container">
<div class="row mt-3">
<div class="col">
<label for="name" class="form-label">Name</label>
<input type="text" class="form-control" id="name" placeholder="Name" required>
<div class="invalid-feedback">
Name can't be empty
</div>
</div>
<div class="col">
<label for="surname" class="form-label">Surname</label>
<input type="text" class="form-control" id="surname" placeholder="Surname" required>
<div class="invalid-feedback">
Surname can't be empty
</div>
</div>
</div>
<div class="row mt-3">
<div class="col">
<label for="email" class="form-label">Email</label>
<input type="email" class="form-control" id="email" placeholder="Email" required>
<div class="invalid-feedback">
invalid email
</div>
</div>
<div class="col-4 text-end">
<label for="email" class="form-label">Role</label>
<select class="form-select" id="validationCustom04" required>
<option selected disabled value="">Choose...</option>
<option>Captain</option>
<option>First Officer</option>
</select>
<div class="invalid-feedback">
Please select role
</div>
</div>
</div>
<div class="row mt-3 ">
<div class="col">
<label for="password1" class="form-label ">Password</label>
<input type="password" class="form-control" id="password1" placeholder="Password">
</div>
<div class="col">
<label for="password2" class="form-label ">Confirm Password</label>
<input type="password" class="form-control" id="password2" placeholder="Password">
<div class="invalid-feedback">
Password not match
</div>
</div>
</div>
<div class="row-cols-2 mt-3">
<button class="btn btn-primary" type="submit">Submit form</button>
</div>
</div>
</form>
</div>
<script src="/validation.js"></script>
<script src="/js/bootstrap.bundle.min.js" ></script>
</body>
What I don't understand is, that your password fields seem to be having a valid class in your posted screenshot. But I can't find it anywhere in your code (neither HTML nor JS).
I'd do it like this:
(Note: I didn't test this code, but it should work. If it works and you want to learn from it, I recommend to read through it step by step and apply it to your logic instead of just copy pasta.)
let form = document.querySelector("form.needs-validations");
// or, to be more specific:
// let form = document.querySelector("form[name='signing-form']")
form.addEventListener("submit",function (ev) {
let pass1 = document.getElementById("password1");
let pass2 = document.getElementById("password2");
// test password check....
if (pass1.value !== pass2.value || pass1.value === "" || pass2.value === "" ){
pass1.classList.add('is-invalid');
pass2.classList.add('is-invalid');
}
if (!form.checkValidity()){
ev.preventDefault();
ev.stopPropagation();
}
form.classList.add("was-validated");
})
Note: the functionality to validate the content of your password-fields will only be triggered once you hit the submit button.

How to compare new password and confirm password using JavaScript Angular

I need to compare below new password field and confirm password field. This is the form
<form novalidate (ngSubmit)="changepasswordform.form.valid && changePassword(this.changepassword, changepasswordform)"
#changepasswordform="ngForm">
<div class="form-group row">
<label for="email5" class="col-sm-5 col-md-5 col-form-label">New Password</label>
<div class="col-sm-7 col-md-7">
<input type="password" class="form-control" pattern="^(?=.*[A-Za-z])(?=.*\d).{8,}$" required
[class.is-invalid]="newpassword.invalid && newpassword.touched" name="newpasswords"
#newpassword="ngModel" [(ngModel)]="changepassword.newPassword"
placeholder="New Password">
<div [class.d-none]="newpassword.valid || newpassword.untouched">
<small class=" text-danger" *ngIf="newpassword.errors?.required">Password is
required</small>
<small *ngIf="newpassword.hasError('pattern')" class=" text-danger">
Password should be 8 characters, at least one
letter and one number</small>
</div>
</div>
</div>
<div class="form-group row">
<label for="email5" class="col-sm-5 col-md-5 col-form-label">Confirm Password</label>
<div class="col-sm-7 col-md-7">
<input type="password" class="form-control"
[class.is-invalid]="repassword.invalid && repassword.touched" name="repassword"
#repassword="ngModel" placeholder="Confirm Password" compare="newpassword"
[(ngModel)]="changepassword.repassword" required>
<div [class.d-none]="repassword.valid || repassword.untouched">
<small *ngIf="repassword.errors?.required" class="text-danger">Confirm password is
required</small>
</div>
<div class="text-danger"
*ngIf="repassword.invalid && (repassword.dirty || repassword.touched)">
<small class="login-val" *ngIf="repassword.errors['compare']"> Confirm password do not
match</small>
</div>
</div>
</div>
</form>
When user type the text box, validation should be check. Do you know how to do this. I need to do this without any library.
Since you are not using reactive forms, you can directly perform a comparison between the models newPassword and repassword to set the error message.
Please refer following stackblitz.
Code: here
Output: here

Error 1068: Property does not exist on type angular 2 (AOT)

I am new in angular 2, i am making a "User Register" form but it shows error in "Property does not exist on type" in Phone number Validation.
I am compiling in JIT and AOT.
In JIT compiler shows error message and run my user register form it is working properly. but when i compile with AOT shows compilation error.
I am reading the angular 2 form validation official doc here is the link Angular 2 form validation
Below is my Html Form and compiler Output
Html Form
<form class="ui large form" method="post" (ngSubmit)="onSubmit(registerForm.form.valid)" #registerForm="ngForm" novalidate>
<sm-loader [complete]="!formSubmited" class="inverted" text="Loading..."></sm-loader>
<div class="form-group">
<div class="col-md-12 img-bottom">
<div class="col-md-offset-4">
<img (click)="profileImage.click()" class="img img-responsive img-circle ui middle aligned tiny circular image profileImage"
[src]="profileImageSrc" />
<input class="form-control user-reg-img" (change)="fileChangeEvent($event)" type="file" accept="image/*" #profileImage [hidden]="true"
/>
</div>
<div class="col-md-12 image-padding">
<span class="user-reg-img-name" (click)="profileImage.click()">{{profileImageName}}</span>
</div>
</div>
</div>
<div class="form-group">
<label><strong>Signup with Email Address:</strong></label>
</div>
<div class="form-group">
<p class="success text-center">{{successMessage}}</p>
<p class="error text-center">{{errorMessage}}</p>
<div class="field">
<input type="text" name="name" placeholder="Name" [(ngModel)]="register.name" #name="ngModel" required class="form-control input-reg"
/>
<div [hidden]="name.valid || name.pristine" class="error text-left">
Name is required
</div>
</div>
</div>
<div class="form-group">
<div class="field">
<input class="form-control input-reg" type="email" name="email" placeholder="Email" [(ngModel)]="register.email" #email="ngModel"
required />
<div [hidden]="email.valid || email.pristine" class="error text-left">
Email is required
</div>
</div>
</div>
<div class="form-group">
<input type="text" id="mobile" class="form-control input-reg" required minlength="10" maxlength="10" name="mobile" [(ngModel)]="register.mobile"
placeholder="Phone Number" #mobile="ngModel" pattern="[0-9]+">
<div *ngIf="mobile.errors && (mobile.dirty || mobile.touched)">
<div class="error text-left" [hidden]="!mobile.errors.required">
Mobile Number is required
</div>
<div class="error text-left" [hidden]="!mobile.errors.minlength">
Mobile Number must be at least 10 characters long.
</div>
<div class="error text-left" [hidden]="!mobile.errors.maxlength">
Monile Number cannot be more than 10 characters long.
</div>
</div>
</div>
<div class="form-group">
<div class="field">
<input class="form-control input-reg" type="password" name="password" placeholder="Password" [(ngModel)]="register.password"
#password="ngModel" required />
<div [hidden]="password.valid || password.pristine" class="error text-left">
Password is required
</div>
</div>
</div>
<div class="form-group">
<input type="checkbox" name="isAgree" [(ngModel)]="register.isAgree" #isAgree="ngModel" required />
<label id="label-terms-cond">I Agree to Post Bucks Terms & Conditions</label>
<div [hidden]="!showTermsAgreeErrorMsg" class="error text-left">
Please agree the terms and conditions to continue
</div>
</div>
<div class="form-group">
<textarea rows="4" class="form-control font-small terms-cond-textarea" rows="7">You must follow any policies made available to you within the Services.</textarea>
</div>
<div class="form-group">
<button class="fluid yellow large ui button btn btn-block btn-warning reg-btn-submit" type="submit">Signup</button>
</div>
</form>
AOT Output
Thanks in advance
Vikram
It looks the JIT compiler will never check the type of mobile.errors, but AOT check it at compilation by looking this line :
<div *ngIf="mobile.errors && (mobile.dirty || mobile.touched)">
According that in this line mobile.errors is a boolean, you'll obtain your traces...
I can't reproduce this bug (version problem ?), but maybe the following code will fix it :
<div *ngIf="(mobile.errors != null) && (mobile.dirty || mobile.touched)">
There is an opened issue here : https://github.com/angular/angular/issues/11425
Here is my answer, there is actual problem of required which is not found under mobile.errors object. below is my single line code.
!mobile.errors['required']
If object field not found then we use as array in template.

AngularJS - How can set the true value for ng-disabled directive, when the page is loaded first time?

I have this form with validation in AngularJS:
<form ng-app="myApp" ng-controller="validateCtrl as validate" name="myForm" action="sendEmail" novalidate>
<div class="form-group">
<input type="email" name="email" class="form-control" ng-model="validate.email" placeholder="Email" required>
<span style="color:yellow" ng-show="myForm.email.$dirty && myForm.email.$invalid">
<span ng-show="myForm.email.$error.required">Email is required.</span>
<span ng-show="myForm.email.$error.email">Invalid email address.</span>
</span>
</div>
<div class="form-group">
<input type="text" name="subject" class="form-control" ng-model="validate.subject" placeholder="Subject" required>
<span style="color:yellow" ng-show="myForm.subject.$dirty && myForm.subject.$invalid">
<span ng-show="myForm.subject.$error.required">Subject is required.</span>
</span>
</div>
<div class="form-group">
<textarea type="text" name="message" class="form-control" ng-model="validate.message" placeholder="Message..." required></textarea>
<span style="color:yellow" ng-show="myForm.message.$dirty && myForm.message.$invalid">
<span ng-show="myForm.message.$error.required">Message is required.</span>
</span>
</div>
<button type="submit" class="btn btn-lg btn-success"
ng-disabled="myForm.email.$dirty && myForm.email.$invalid ||
myForm.subject.$dirty && myForm.subject.$invalid ||
myForm.message.$dirty && myForm.message.$invalid"></button>
</form>
The button is disabled until the email, subject and message aren't correct. Ok, it's fine. But that is true, only if I have already interacted with the form.
In fact, when the page is loaded the first time and I haven't interacted with the form yet, the button is enabled. So, if I click it, I could send an empy email! I would that when the page is loaded the button is disabled and when I fill the fields become enabled.
How can I do that?
Thanks.
You first condition can be ng-disabled=" myForm.email.$invalid . Remove "myForm.email.$dirty
Try like this
<form name="postForm" method="POST" novalidate>
<div class="col-md-8">
<div class="col-md-12">
<div class="col-md-12"><legend>Submit New Post</legend></div>
</div>
<div class="col-md-12 form-group">
<div class="col-md-12" ng-class="{ 'has-error' : postForm.title.$invalid && !postForm.title.$pristine }">
<input type="text" placeholder="Write Title" class="form-control" name="title" ng-model="post.title" required>
<p ng-show="postForm.title.$invalid && !postForm.title.$pristine" class="text-danger">* Write Post Title</p>
</div>
</div>
<div class="col-md-12 form-group">
<div class="col-md-12" ng-class="{ 'has-error' : postForm.url.$invalid && !postForm.url.$pristine }">
<input type="url" placeholder="Write URL" class="form-control" name="url" ng-model="post.url" >
<p ng-show="postForm.url.$invalid && !postForm.url.$pristine" class="text-danger">* Write URL in http:// or https:// Format</p>
</div>
</div>
<div class="col-md-12">
<div class="col-md-12" >
<p class="text-danger">{{msg}}</p>
</div>
</div>
<div class="col-md-12 form-group">
<div class="col-md-12"><button type="submit" class="btn btn-info" ng-disabled="postForm.$invalid" ng-click="submitForm(....)">Submit</button>
<img src="img/loading.gif" ng-show="loading" /></div>
</div>
</div>
</form>
On your submit button, modify the ng-disabled to this:
ng-disabled="myForm.$invalid || myForm.$pristine">
In this case, you don't have to validate all your inputs separetely. Just test if your form is invalid OR if the user never interacted with it yet.
A form in AngularJS has two different states: pristine and dirty. The pristine indicates that your form was never touched. And dirty is the opposite. When the user set any value to one of your inputs, the angular change the state of your form from pristine to dirty.
I guess this post is a good reference to read about forms in angular

angularJS form validation only working for the first time

I'm working on form validations in angularjs and so far i have completed 99%. But the issue is my form validation works correct only for first time submit only. it's confusing to explain but i'll try my best to explain :P .here it is. When i reset my form it is showing error messages that the fields are empty(As it should).like this
After that if i fill 2 fields and submit again i'll work correctly as it should.like this
Now my problem comes.If i reset my form (fields get cleared) and submit the form, only description field error is shown but not in other two.like this
My code
<form name="userForm" ng-submit="submitForm(userForm.$valid, user)" novalidate>
<!-- NAME -->
<div class="form-group" ng-class="{ 'has-error' : userForm.name.$invalid && userForm.name.$dirty && submitted || (userForm.name.$invalid && userForm.name.$pristine) && submitted }">
<label>Name*</label>
<input type="text" name="name" class="item-input-wrapper" ng-model="user.name" required>
<label><p ng-show="submitted && userForm.name.$error.required" class="help-block "><font color="#009ACD">You name is required.</font></p></label>
</div>
<!-- EMAIL -->
<div class="form-group" ng-class="{ 'has-error' : userForm.email.$invalid && userForm.email.$dirty && submitted || userForm.email.$invalid && userForm.email.$pristine && submitted }">
<label>Email</label>
<input type="email" name="email" class="item-input-wrapper"ng-model="user.email" required >
<label><p ng-show="userForm.email.$invalid && userForm.email.$dirty && submitted || userForm.email.$invalid && userForm.email.$pristine && submitted" class="help-block"><font color="#009ACD">Enter a valid email.</font></p></label>
</div>
<!-- DESCRIPTION -->
<div class="form-group" ng-class="{ 'has-error' : userForm.username.$invalid && userForm.username.$dirty && submitted || userForm.username.$invalid && userForm.username.$pristine && submitted }">
<label>Description</label>
<input type="text" name="username" class="item-input-wrapper" ng-model="user.username" ng-minlength="5" ng-maxlength="60" required>
<label><font color="white"><p ng-show="userForm.username.$error.minlength && submitted" class="help-block"><font color="#009ACD">Description is too short.</font></p></label>
<label><p ng-show="userForm.username.$error.maxlength && submitted" class="help-block"><font color="#009ACD">Description is too long.</font></p></label>
<label><p ng-show="submitted && userForm.username.$error.required" class="help-block "><font color="#009ACD">Description is required.</font></p></label>
</div>
<div class="col"style="text-align: center">
<button align="left"class="button button-block button-reset" type="reset" value="Reset" style="display: inline-block;width:100px;text-align:center "
ng-click="submitted=false" padding-top="true">Reset</button>
<button class="button button-block button-positive" style="display: inline-block;width:100px "
ng-click="submitted=true" type="submit" padding-top="true">Submit</button>
</div>
</form>
</div>
$setPristine(); may be useful for what you looking for. Try to add like this as shown below...
<button class="button" type="reset" ng-click="form.$setPristine()">Reset</button>
For further information and for working demo refer the below link
AngularJS does not proper handle button type="reset"?
you can also refer the below link for setting up the form to pristine state
Reset form to pristine state (AngularJS 1.0.x)
figured out the solution
inside your controller add this
$scope.reset = function() {
$scope.user = angular.copy($scope.orig);
$scope.userForm.$setPristine();
};
Here 'userForm' should be your form name and 'user' should be your model.
This works for me.try it.
<form name="forms.sample" novalidate>
<md-input-container class="md-block" flex-gt-sm>
<label>Name:</label>
<input ng-focus="focus=true" ng-blur="focus=false" style="width:400px;" class="form-control" name="Name" type="text" data-ng-model="Name" ng-pattern="SomePattern" required placeholder="enter the Name here" />
<div ng-messages for="forms.sample.Name.$error" ng-if="!focus">
<div ng-if='forms.sample.Name.$touched' ng-message="required">This is required.</div>
<div ng-if='forms.sample.Name.$touched' ng-message="pattern">Enter a valid domain name</div>
</div>
</md-input-container>
</form>

Categories

Resources