Reputation: 151
I have some problem in my code and I'm trying to understand reason of that and where it comes from. So here I've added in is-valid and is-invalid classes to my input validators, also I've tried to use has-success and has-error classes,but as I guess it not work for bootstrap 4. This is my component.html `
<h1 class="page-header">Register Page</h1>
<!-- Registration Form -->
<form [formGroup]='form' (submit)='onRegisterSubmit()' >
<div class="form-group">
<label for="username">Username</label>
<div [ngClass]="{'is-invalid': (form.controls['username'].errors && form.controls['username'].dirty), 'is-valid': !form.controls['username'].errors}">
<input type="text" name="username" formControlName="username" class="form-control" autocomplete="off" placeholder="*Username">
<ul class="help-block">
<li *ngIf="form.controls['username'].errors?.required && form.controls['username'].dirty">This field is required</li>
<li *ngIf="form.controls['username'].errors?.minlength && form.controls['username'].dirty || form.controls['username'].errors?.maxlength && form.controls['username'].dirty ">Minimum characters: 3, Maximum characters: 15</li>
<li *ngIf="form.controls['username'].errors?.validateUsername && form.controls['username'].dirty">Username must not have any special characters</li>
</ul>
</div>
</div>
<div class="form-group">
<label for="email">E-mail</label>
<div [ngClass]="{'is-invalid': (form.controls['email'].errors && form.controls['email'].dirty), 'is-valid': !form.controls['email'].errors}">
<input type="text" name="email" class="form-control" formControlName="email" autocomplete="off" placeholder="*E-mail">
<ul class="help-block">
<li *ngIf="form.controls['email'].errors?.minlength && form.controls['email'].dirty || form.controls['email'].errors?.maxlength && form.controls['email'].dirty ">Minimum characters: 5, Maximum characters: 30</li>
<li *ngIf="form.controls['email'].errors?.required && form.controls['email'].dirty">This field is required</li>
<li *ngIf="form.controls['email'].errors?.validateEmail && form.controls['email'].dirty">This must be a valid email</li>
</ul>
</div>
</div>
<div class="form-group">
<label for="password">Password</label>
<div [ngClass]="{'is-invalid': (form.controls['password'].errors && form.controls['password'].dirty), 'is-valid': !form.controls['password'].errors}">
<input type="password" name="password" formControlName="password" class="form-control" autocomplete="off" placeholder="*Password">
<ul class="help-block">
<li *ngIf="form.controls['password'].errors?.required && form.controls['password'].dirty">This field is required</li>
<li *ngIf="form.controls['password'].errors?.minlength && form.controls['password'].dirty || form.controls['password'].errors?.maxlength && form.controls['password'].dirty ">Minimum characters: 8, Maximum characters: 35</li>
<li *ngIf="form.controls['password'].errors?.validatePassword && form.controls['password'].dirty">Must have at least one uppercase, lowercase, special character, and number</li>
</ul>
</div>
</div>
<div class="form-group">
<label for="confirm">Confirm Password</label>
<div [ngClass]="{'is-invalid': (form.controls['confirm'].errors && form.controls['confirm'].dirty) || (form.errors?.matchingPasswords && form.controls['confirm'].dirty), 'is-valid': !form.controls['confirm'].errors && !form.errors?.matchingPasswords}">
<input type="password" name="confirm" class="form-control" formControlName="confirm" autocomplete="off" placeholder="*Confirm Password">
<ul class="help-block">
<li *ngIf="form.controls['confirm'].errors?.required && form.controls['confirm'].dirty">This field is required</li>
<li *ngIf="form.errors?.matchingPasswords && form.controls['confirm'].dirty">Password do not match!</li>
</ul>
</div>
</div>
<input [disabled]="!form.valid" type="submit" class="btn btn-primary" value="Submit">
</form>
And this is my component.ts `
import { Component, OnInit, group } from '@angular/core';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
@Component({
selector: 'app-register',
templateUrl: './register.component.html',
styleUrls: ['./register.component.css']
})
export class RegisterComponent implements OnInit {
form:FormGroup;
constructor(private formBuilder:FormBuilder) {
this.createForm();
}
createForm(){
this.form=this.formBuilder.group({
email:['',Validators.compose([
Validators.required,
Validators.minLength(5),
Validators.maxLength(30),
this.validateEmail
])],
username:['',Validators.compose([
Validators.required,
Validators.minLength(3),
Validators.maxLength(15),
this.validateUsername
])],
password:['',Validators.compose([
Validators.required,
Validators.minLength(8),
Validators.maxLength(35),
this.validatePassword
])],
confirm:['',Validators.required]
},{validator:this.matchingPasswords('password','confirm')});
}
validateEmail(controls){
const regExp = new RegExp(
/^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/
);
if(regExp.test(controls.value)){
return null;
}else{
return {'validateEmail':true};
}
}
validateUsername(controls){
const regExp = new RegExp(/^[a-zA-z0-9]+$/);
if(regExp.test(controls.value)){
return null;
}else{
return {'validateUsername':true};
}
}
validatePassword(controls){
const regExp = new RegExp(/^(?=.*?[a-z])(?=.*?[A-Z])(?=.*?[\d])(?=.*?[\W]).{8,35}$/);
if(regExp.test(controls.value)){
return null;
}else{
return {'validatePassword':true};
}
}
matchingPasswords(password,confirm){
return (group:FormGroup)=>{
if(group.controls[password].value === group.controls[confirm].value){
return null;
}else{
return {'matchingPasswords':true};
}
}
}
onRegisterSubmit(){
console.log("submitted");
}
ngOnInit() {
}
}
I need that, when user typing something in input, it will change class to success or error. How can I do this?
Upvotes: 1
Views: 3052
Reputation: 739
i know that your question is for long time ago, but it is the best way to validate the form-control input field by reactive form technique and bootstrap 4 to display the validation. first you need to write some code for your form : in html section:
<form [formGroup]="myForm">
<div class="form-group">
<label for="name">first Name: </label>
<input type="text" class="form-control" formControlName="firstName" id="name">
<div *ngIf="firstName.touched && firstName.invalid" class="alert alert-danger">
<div *ngIf="firstName.errors.required">filling name is required!</div>
</div>
</div>
</form>
in ts file, you should implement the logic to conduct the validation.
in ts file:
myForm = new FormGroup({
'firstName':new FormControl('',Validators.required)
})
//getter method
get firstName(){
this.myForm.get('firstName');
}
now you can see that the validation is working. now to give style to input field to show the red border around the invalid input, just go to css file of component and add this class to the css file:
/// invalid
.form-control.ng-touched.ng-invalid{border:2px solid red;}
///valid
.form-control.ng-touched.ng-invalid{border:2px solid green;}
with this technique is not required that you use ng class.
Upvotes: 3