This dynamic form use template driven form And Very simple to use
- *ngFor array of form objects
- will call template for the input suplied by each form object from ngfor
- inside step 2 will use app- selector of component to display error
inside component.ts
constructor(private title: Title) {
    title.setTitle('Login');
    const usernameForm: BaseForm = new BaseForm('Username', 'Username', 'username', 'text');
    usernameForm.rules = {
      'required': true,
      'minlength': 5,
      'maxlength': 7,
      'pattern': '[\\w]*',
      'patternInfo': 'Only word and number no spaces and symbols'
    };
    usernameForm.value = 'myName';
    const passwordForm: BaseForm = new BaseForm('Password', 'Password', 'password', 'password');
    passwordForm.rules = {
      'required': true,
      'maxlength': 10
    };
    this.baseForms.push(usernameForm, passwordForm);
  }then in the component.htmll
<div class="row">
  <div class="offset-3 col-6">
    <form #loginForm="ngForm" novalidate (submit)="formSubmit(loginForm)">
      <span *ngFor="let baseForm of this.baseForms">
        <app-style-stack [parentForm]="loginForm" [baseForm]="baseForm"></app-style-stack>
      </span>
      <button [disabled]="!loginForm.valid"  class="btn btn-success" type="submit">Login</button>
    </form>
  </div>
</div>- required : boolean
- minlength: number
- maxlength: number
- pattern : string regex
- patternInfo: String the info of regex rule to be displayed to user if pattern not satisfied
- in BaseForm Object set the .value, it will be 2 way binding
- all inside src/app/forms
- optional the src/style.css for form animation for this demo
- bootstrap v4 for this demo