Angular

Multi Step Form In Angular.

What Is Multi Step Form?

Multi step Form is a long form broken into multi steps. It is not a multi forms rather than multi steps in a single long form. The reason behind it, short form is more easy to complete than long form. It is more comfortable for users to fill the form step by step because their mind should process fewer fields at a time.

Now a days multi step form is more popular than regular form , as it is more user friendly rather than regular form. The multi step form is the best solution when there are too many fields in a from. So breaking large form into multiple step is more user friendly.

It is used to make long form, such as checkout page , registration form etc.,less intimidating and daunting.

Why Use Multi step Form?
1. It is more comfortable than regular form.
2. It is easy to fill short form than long form.
3. It can increase engagement.
4. It reduce psychological friction.

Below are the steps to implement multi step form in Angular.

Step 1: Create New App.

ng new angular-multistep

Step 2: Import Module.

In this step, just import FormsModule, ReactiveFormsModule, and BrowserAnimationsModule module for creating this example. Open src/app/app.module.ts and add below lines.

import { BrowserModule } from '@angular/platform-browser';
import {FormsModule, ReactiveFormsModule} from '@angular/forms';

@NgModule({
  declarations: [
    AppComponent     
  ],
  imports:[
     BrowserModule,
     ReactiveFormsModule,
     FormsModule,
  ],
  providers: [],
  bootstrap: [AppComponent]   
})
export class AppModule { }

Step 3 : Update ts file.

Add below code in src/app/app.component.ts

import { Component, OnInit } from '@angular/core';
import { FormControl,FormGroup,Validators,FormBuilder } from '@angular/forms';


@Component({
  selector: 'app-multistep',
  templateUrl: './multistep.component.html',
  styleUrls: ['./multistep.component.css']
})
export class MultistepComponent implements OnInit {

  personalDetails!: FormGroup;
  addressDetails!: FormGroup;
  educationalDetails!: FormGroup;
  personal_step = false;
  address_step = false;
  education_step = false;
  step = 1;

  constructor(private formBuilder: FormBuilder) { }

  ngOnInit() {

		this.personalDetails = this.formBuilder.group({
			name: ['', Validators.required],
			email: ['', Validators.required],
			phone: ['',Validators.required]
		});

		this.addressDetails = this.formBuilder.group({
			city: ['', Validators.required],
			address: ['', Validators.required],
			pincode: ['',Validators.required]
		});

		this.educationalDetails = this.formBuilder.group({
			highest_qualification: ['', Validators.required],
			university: ['', Validators.required],
			total_marks: ['',Validators.required]
		});
  }

  get personal() { return this.personalDetails.controls; }
  get education() { return this.educationalDetails.controls; }
  get address() { return this.addressDetails.controls; }

  next(){

	if(this.step==1){
          this.personal_step = true;
          if (this.personalDetails.invalid) { return  }
          this.step++
    }

    if(this.step==2){
        this.address_step = true;
        if (this.addressDetails.invalid) { return }
		    this.step++;
    }

  }

  previous(){

    this.step--
    if(this.step==1){
      this.personal_step = false;
    }
    if(this.step==2){
      this.education_step = false;
    }
  }

  submit(){

    if(this.step==3){
      this.education_step = true;
      if (this.educationalDetails.invalid) { return }
    }
  }
}

Step 4 : Update html file.

Add below code in src/app/app.component.html.

 <div class="row"> 
    <div class="col-md-12 col-md-offset-3">
        <form [formGroup]="personalDetails" id="msform">
            <!-- progressbar -->
            <ul id="progressbar">
                <li [ngClass]="step>=1 ? 'active ' : 'inactive'">Personal Details</li>
                <li [ngClass]="step>=2 ? 'active' : 'inactive'">Social Profiles</li>
                <li [ngClass]="step==3 ? 'active' : 'inactive'">Account Setup</li>
            </ul>
            <!-- fieldsets -->

            <fieldset  *ngIf="step == 1" >
                <h2 class="fs-title">Personal Details</h2>
                <input type="text" formControlName="name"  [ngClass]="{ 'is-invalid': personal_step && personal.name.errors }" placeholder="Full Name"/>
                <div *ngIf="personal_step && personalDetails.controls.name.errors">
                    <div *ngIf="personal.name.errors?.required">Name is required</div>
                </div>
                <input type="text" formControlName="email" name="email" placeholder="Email"/>
                <div *ngIf="personal_step && personalDetails.controls.email.errors">
                  <div *ngIf="personal.email.errors?.required">Email is required</div>
               </div>
                <input type="text" formControlName="phone" name="phone" placeholder="Phone"/>
                <div *ngIf="personal_step && personalDetails.controls.phone.errors">
                  <div *ngIf="personal.phone.errors?.required">Phone is required</div>
              </div>
                <input (click)="next()" type="button" name="next" class="next action-button" value="Next"/>
            </fieldset>
		</form>
		 <form [formGroup]="addressDetails" id="msform">
            <fieldset *ngIf="step == 2" >
                <h2 class="fs-title">Address Details</h2>
                <input type="text" formControlName="city"  placeholder="City"/>
				<div *ngIf="address_step && addressDetails.controls.city.errors">
                    <div *ngIf="address.city.errors?.required">City is required</div>
                </div>
                <textarea rows="5" cols="5" formControlName="address"  placeholder="address"></textarea>
				<div *ngIf="address_step && addressDetails.controls.address.errors">
                    <div *ngIf="address.address.errors?.required">Address is required</div>
                </div>
                <input type="text" formControlName="pincode"  placeholder="Pincode"/>
				<div *ngIf="address_step && addressDetails.controls.pincode.errors">
                    <div *ngIf="address.pincode.errors?.required">Pincode is required</div>
                </div>
                <input (click)="previous()" type="button" name="previous" class="previous action-button-previous" value="Previous"/>
                <input  (click)="next()" type="button" name="next" class="next action-button" value="Next"/>
            </fieldset>
		</form>
		 <form [formGroup]="addressDetails" id="msform">
            <fieldset *ngIf="step == 3">
                <h2 class="fs-title">Educational Details</h2>
                <input type="text" formControlName="highest_qualification" placeholder="Highest Qualification"/>
				<div *ngIf="education_step && educationalDetails.controls.highest_qualification.errors">
                    <div *ngIf="education.highest_qualification.errors?.required">Highest qualification is required</div>
                </div>
                <input type="text" formControlName="university"  placeholder="University"/>
				<div *ngIf="education_step && educationalDetails.controls.university.errors">
                    <div *ngIf="education.university.errors?.required">University is required</div>
                </div>
                <input type="text" formControlName="total_marks" placeholder="Total Marks"/>
				<div *ngIf="education_step && educationalDetails.controls.total_marks.errors">
                    <div *ngIf="education.total_marks.errors?.required">Total marks is required</div>
                </div>
                <input (click)="previous()" type="button" name="previous" class="previous action-button-previous" value="Previous"/>
                <input (click)="submit()"type="submit" name="submit" class="submit action-button" value="Submit"/>
            </fieldset>
        </form>

    </div>
</div>
 

Step 5 : Update css file.

Add below code in src/app/app.component.css.

/*form styles*/
#msform {
    text-align: center;
    position: relative;
    margin-top: 30px;
}

#msform fieldset {
    background: white;
    border: 0 none;
    border-radius: 0px;
    box-shadow: 0 0 15px 1px rgba(0, 0, 0, 0.4);
    padding: 20px 30px;
    box-sizing: border-box;
    width: 80%;
    margin: 0 10%;

    /*stacking fieldsets above each other*/
    position: relative;
}

/*Hide all except first fieldset*/
#msform fieldset:not(:first-of-type) {
    display: none;
}

/*inputs*/
#msform input, #msform textarea {
    padding: 15px;
    border: 1px solid #ccc;
    border-radius: 0px;
    margin-bottom: 10px;
    width: 100%;
    box-sizing: border-box;
    font-family: montserrat;
    color: #2C3E50;
    font-size: 13px;
}

#msform input:focus, #msform textarea:focus {
    -moz-box-shadow: none !important;
    -webkit-box-shadow: none !important;
    box-shadow: none !important;
    border: 1px solid #ee0979;
    outline-width: 0;
    transition: All 0.5s ease-in;
    -webkit-transition: All 0.5s ease-in;
    -moz-transition: All 0.5s ease-in;
    -o-transition: All 0.5s ease-in;
}

/*buttons*/
#msform .action-button {
    width: 100px;
    background: #ee0979;
    font-weight: bold;
    color: white;
    border: 0 none;
    border-radius: 25px;
    cursor: pointer;
    padding: 10px 5px;
    margin: 10px 5px;
}

#msform .action-button:hover, #msform .action-button:focus {
    box-shadow: 0 0 0 2px white, 0 0 0 3px #ee0979;
}

#msform .action-button-previous {
    width: 100px;
    background: #C5C5F1;
    font-weight: bold;
    color: white;
    border: 0 none;
    border-radius: 25px;
    cursor: pointer;
    padding: 10px 5px;
    margin: 10px 5px;
}

#msform .action-button-previous:hover, #msform .action-button-previous:focus {
    box-shadow: 0 0 0 2px white, 0 0 0 3px #C5C5F1;
}

/*headings*/
.fs-title {
    font-size: 18px;
    text-transform: uppercase;
    color: #2C3E50;
    margin-bottom: 10px;
    letter-spacing: 2px;
    font-weight: bold;
}

.fs-subtitle {
    font-weight: normal;
    font-size: 13px;
    color: #666;
    margin-bottom: 20px;
}

/*progressbar*/
#progressbar {
    margin-bottom: 30px;
    overflow: hidden;
    /*CSS counters to number the steps*/
    counter-reset: step;
}

#progressbar li {
    list-style-type: none;
    color: white;
    text-transform: uppercase;
    font-size: 9px;
    width: 33.33%;
    float: left;
    position: relative;
    letter-spacing: 1px;
}

#progressbar li:before {
    content: counter(step);
    counter-increment: step;
    width: 24px;
    height: 24px;
    line-height: 26px;
    display: block;
    font-size: 12px;
    color: #333;
    background: white;
    border-radius: 25px;
    margin: 0 auto 10px auto;
}

/*progressbar connectors*/
#progressbar li:after {
    content: '';
    width: 100%;
    height: 2px;
    background: white;
    position: absolute;
    left: -50%;
    top: 9px;
    z-index: -1; /*put it behind the numbers*/
}

#progressbar li:first-child:after {
    /*connector not needed before the first step*/
    content: none;
}

/*marking active/completed steps green*/
/*The number of the step and the connector before it = green*/
#progressbar li.active:before, #progressbar li.active:after {
    background: #ee0979;
    color: white;
}



#progressbar li.inactive:before{
    background: burlywood;
    color: #000;

}

fieldset {
   /* for chrome and safari*/
  -webkit-animation-duration: .25ms;-webkit-animation-name: slidein;

   /*for firefox*/
  -moz-animation-duration: 1s;-moz-animation-name: slidein;

   /* for opera*/
   -o-animation-duration: 1s;-o-animation-name: slidein;

  /* Standard syntax*/
      animation-duration: 1s;animation-name: slidein;
  }

   @-webkit-keyframes slidein {
        from { margin-right:100%;width:300%;}
        to { margin-right: 0%;width: 100%;           }
  }

  @-moz-keyframes slidein {
           from {
               margin-left: 100%;width: 300%;
           }
           to {
               margin-left: 0%; width: 100%;
           }
    }
  @-o-keyframes slidein {
           from {
               margin-left: 100%;width: 300%;
           }

           to {
               margin-left: 0%;width: 100%;
           }
  }
  @keyframes slidein {
           from {
               margin-left: 100%;width: 300%;
           }

           to {
               margin-left: 0%;width: 100%;
           }
  }

 That’s all about multi step form in Angular. After writing above code open http://localhost:4200/.

Reactive Form Validation In Angular.

Related Articles

Leave a Reply

Back to top button