Coder Social home page Coder Social logo

mithila26 / multi-step-dynamic-form-in-angular Goto Github PK

View Code? Open in Web Editor NEW

This project forked from piyalidas10/multi-step-dynamic-form-in-angular

0.0 0.0 0.0 2.37 MB

Multi Step Dynamic Form in Angular

JavaScript 5.64% TypeScript 65.93% CSS 5.14% HTML 23.29%

multi-step-dynamic-form-in-angular's Introduction

Multi Step Dynamic Form in Angular

Passing formname, form fields, step details to create dynamic multi step form with prev/next button

  1. Save button should be clicked to save data
  2. Click on prev button to go previous form with already submitted value
  3. At last step, you will get submit button instead of next to save total data

Run the application

ng serve
localhost:4200

Multi Step Dynamic Form in Angular

App Component

static JSON file

this.data = [
      {
        'stepname': 'basic',
        'formFields': [
          {
          'key': 'firstName',
          'input': 'text',
          'valids': [{
              'valid': 'required',
              'error': 'firstName is required'
            },
            {
              'valid': 'pattern',
              'validator': '^[a-zA-Z]+$',
              'error': 'firstName is accept only text'
            },
            {
              'valid': 'minlength',
              'length': 3,
              'error': 'firstName must be at least 3 characters'
            }
          ]
          },
          {
            'key': 'middleName',
            'input': 'text',
            'valids': []
          },
          {
            'key': 'lastName',
            'input': 'text',
            'valids': [{
                'valid': 'required',
                'error': 'lastName is required'
              },
              {
                'valid': 'pattern',
                'validator': '^[a-zA-Z]+$',
                'error': 'lastName is accept only text'
              },
              {
                'valid': 'minlength',
                'length': 3,
                'error': 'lastName must be at least 3 characters'
              }
            ]
          },
          {
            'key': 'marital status',
            'input': 'select',
            'items': [{
                'name': 'married',
                'id': 0
              },
              {
                'name': 'unmarried',
                'id': 1
              }
            ],
            'valids': []
          },
          {
            'key': 'gender',
            'input': 'radio',
            'items': [{
                'name': 'male',
                'id': 0
              },
              {
                'name': 'female',
                'id': 1
              }
            ],
            'valids': []
          }
        ]
      },
      {
        'stepname': 'contact',
        'formFields': [
          {
            'key': 'emailId',
            'input': 'email',
            'valids': [{
                'valid': 'required',
                'error': 'emailId is required'
              },
              {
                'valid': 'emailId',
                'error': 'emailId must be valid'
              }
            ]
          },
          {
            'key': 'mobile',
            'input': 'text',
            'valids': [{
                'valid': 'required',
                'error': 'mobile is required'
              },
              {
                'valid': 'pattern',
                'validator': '^[0-9]{10}$',
                'error': 'mobile is accept only number and maximum 10 numbers '
              }
            ]
          },
        ]
      },
      {
        'stepname': 'other',
        'formFields': [
          {
            'key': 'country',
            'input': 'text',
            'valids': [{
                'valid': 'required',
                'error': 'country is required'
              },
            ]
          },
          {
            'key': 'state',
            'input': 'text',
            'valids': [{
                'valid': 'required',
                'error': 'state is required'
              },
            ]
          }
        ]
      }
    ];

Multistepform component

Passing all details though the form component

<app-form *ngIf="stepItems && startingIndex < countSteps"
    [countSteps]="countSteps"
    [stepNo]="startingIndex"
    [formFields]="data[startingIndex].formFields"
    [formValues]="formValues"
    [stepName]="data[startingIndex].stepname"
    (formData)="getFormData($event)"
    (newStep)="onnewStep($event)"
    ></app-form>

Form component

Dynamically form is generating regarding passsing values from multistepform component

<form [formGroup]="formName" #formDir="ngForm" appFocus (ngSubmit)="formDir.form.valid && submit(formDir)">
<div class="row" *ngFor="let form of formFields; let i = index">
    <div class="col-12 form-group" *ngIf="form.input == 'text'">
      <label>{{form.key}}
        <span class="required" *ngIf="formName.get(form.key).hasError('required')">*</span>
      </label>
      <input [type]="form.input" [formControlName]="form.key" class="form-control" [ngClass]="{'is-invalid' : formName.get(form.key).errors && formDir.submitted }">
      <div *ngIf="!formName.get(form.key).valid && formName.get(form.key).errors && formDir.submitted">
        <div *ngFor="let err of form.valids; let k = index">
          <span class="error" *ngIf="formName.get(form.key).hasError(err.valid)">{{err.error}}</span>
        </div>
      </div>
    </div>
    <div class="col-12 form-group" *ngIf="form.input == 'email'">
      <label>{{form.key}}
        <span class="required" *ngIf="formName.get(form.key).hasError('required')">*</span>
      </label>
      <input [type]="form.input" [formControlName]="form.key" class="form-control" [ngClass]="{'is-invalid' : formName.get(form.key).errors && formDir.submitted }">
      <div *ngIf="!formName.get(form.key).valid && formName.get(form.key).errors && formDir.submitted">
        <div *ngFor="let err of form.valids; let k = index">
          <span class="error" *ngIf="formName.get(form.key).hasError(err.valid)">{{err.error}}</span>
        </div>
      </div>
    </div>
    <div class="col-12 form-group" *ngIf="form.input == 'password'">
      <label>{{form.key}}
        <span class="required" *ngIf="formName.get(form.key).hasError('required')">*</span>
      </label>
      <input [type]="form.input" minlength="3" [formControlName]="form.key" class="form-control" [ngClass]="{'is-invalid' : formName.get(form.key).errors && formDir.submitted }">
      <div *ngIf="!formName.get(form.key).valid && formName.get(form.key).errors && formDir.submitted">
        <div *ngFor="let err of form.valids; let k = index">
          <span class="error" *ngIf="formName.get(form.key).hasError(err.valid)">{{err.error}}</span>
        </div>
      </div>
    </div>
    <div class="col-12 form-group" *ngIf="form.input == 'select'">
      <label>{{form.key}}
        <span class="required" *ngIf="formName.get(form.key).hasError('required')">*</span>
      </label>
      <select [formControlName]="form.key" class="form-control" [ngClass]="{'is-invalid' : formName.get(form.key).errors && formDir.submitted }">
        <option *ngFor="let item of form.items; let j = index" [value]="item.id" [selected]="formValues[form.key]">
          {{item.name}}
        </option>
      </select>
      <div *ngIf="!formName.get(form.key).valid && formName.get(form.key).errors && formDir.submitted ">
        <div *ngFor="let err of form.valids; let k = index">
          <span class="error" *ngIf="formName.get(form.key).hasError(err.valid)">{{err.error}}</span>
        </div>
      </div>
    </div>
    <div class="col-12 form-group" *ngIf="form.input == 'radio'">
      <label>{{form.key}}
        <span class="required" *ngIf="formName.get(form.key).hasError('required')">*</span>
      </label>
      <div class="form-group">
        <div class="form-check-inline" *ngFor="let item of form.items; let j = index">
          <label class="form-check-label">
            <input [type]="form.input" class="form-check-input" [formControlName]="form.key" [value]="item.id"
              [ngClass]="{'is-invalid' : formName.get(form.key).errors && formDir.submitted }" name="form.key" [checked]="formValues[form.key]">{{item.name}}
          </label>
        </div>
        <div *ngIf="!formName.get(form.key).valid && formName.get(form.key).errors && formDir.submitted">
          <div *ngFor="let err of form.valids; let k = index">
            <span class="error" *ngIf="formName.get(form.key).hasError(err.valid)">{{err.error}}</span>
          </div>
        </div>
      </div>
    </div>
    <div class="col-12 form-group" *ngIf="form.input == 'checkbox'">
      <label>{{form.key}}
        <span class="required" *ngIf="formName.get(form.key).hasError('required')">*</span>
      </label>
      <div class="form-group">
        <div class="form-check-inline" *ngFor="let item of form.items; let j = index">
          <label class="form-check-label">
            <input [type]="form.input" class="form-check-input" [formControlName]="form.key" [value]="item.id"
              [ngClass]="{'is-invalid' : formName.get(form.key).errors && formDir.submitted }" name="form.key" [checked]="formValues[form.key]">{{item.name}}
          </label>
        </div>
        <div *ngIf="!formName.get(form.key).valid && formName.get(form.key).errors && formDir.submitted">
          <div *ngFor="let err of form.valids; let k = index">
            <span class="error" *ngIf="formName.get(form.key).hasError(err.valid)">{{err.error}}</span>
          </div>
        </div>
      </div>
    </div>
  </div>
  <div class="row">
    <div class="col-6 form-group text-left">
      <button type="button" class="btn btn-default" [disabled]="stepNo === 0" (click)="gotoStep(stepNo-1)">Prev</button>
    </div>
    <div class="col-6 form-group text-right">
      <button type="submit" *ngIf="stepNo !== countSteps - 1" class="btn btn-success">Next</button>
      <button type="submit" *ngIf="stepNo === countSteps - 1" class="btn btn-success">Submit</button>
    </div>
  </div>
  </form>

formDir.form.valid && submit(formDir) - form will be submitted when form is valid and button type should be submit.

submit(myForm: NgForm) {
	    console.log('Form details => ', this.formName.value);
	      const obj = Object.assign(this.formName.value, {'formName': this.stepName});
	      this.formData.emit(obj);
	      this.newStep.emit(this.stepNo + 1);
	      myForm.resetForm();
	  }

submit function is calling while submitting the form. Form value is emitting to the multi step component and step no is increasing to emit also. With increasing step no, next form will be generated.

createForm function is using to create the form with respective formName.

createForm() {
	    this.formName = new FormGroup({});
	    if (this.formName && Object.keys(this.formValues).length > 0) {
	      console.log(this.formName);
	      setTimeout(() => {
	        this.formName.patchValue(this.formValues);
	      }, );
	    }
	    this.validateForm();
	  }

Multi Step Dynamic Form in Angular

See in this image, for FirstName and LastName we are getting 3 validatorArr because from JSON data we are passing 3 valids array.

Creating this validation error checking functionality using the validateForm method,

validateForm() {
    this.formFields.forEach(element => {
      const validatorsArr: ValidatorFn[] = [];
      if (element.valids.length > 0) {


        element.valids.forEach(val => {
          if (val.valid === 'required' || val.valid === 'email') {
            validatorsArr.push(Validators[val.valid]);
          }
          if (val.valid === 'pattern') {
            validatorsArr.push(
              Validators.pattern(val.validator)
            );
         }
         if (val.valid === 'minlength') {
            validatorsArr.push(
              Validators.minLength(val.length)
            );
          }
        });


        this.formName.addControl(element.key, new FormControl('', validatorsArr));
      } else {
        this.formName.addControl(element.key, new FormControl(''));
      }
      console.log('validatorsArr => ', validatorsArr);
    });
  }

multi-step-dynamic-form-in-angular's People

Contributors

piyalidas10 avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.