Search code examples
javascriptangularangular4-forms

How to set ngIf dynamic condition in dynamic form in angular 4


I am creating a dynamic form where I am populating the fields dynamically based on the response from JSON like.

Eg:-

[{
  "type":"text",
  "required":true,
  "minlength": 3,
  "maxlength":5,
  "name":"fname",
  "visibility":true
},
{
  "type":"text",
  "required":true,
  "minlength": 3,
  "maxlength":5,
  "name":"lname",
  "visibility":"fname == 'abc' || fname == 'xyz'"
},
{
  "type":"text",
  "required":true,
  "minlength": 3,
  "maxlength":5,
  "name":"fid",
  "visibility":true
},
{
  "type":"text",
  "required":true,
  "minlength": 3,
  "maxlength":5,
  "name":"lid",
  "visibility":"fid == 1 || fid == 4"
}]

I have a usecase where the second field should be visible only when the first field should have the values 'abc' or 'xyz'(Condition is written in the JSON property).How can that be achieved dynamically?


Solution

  • Create evaluation method in component:

     isVisible(value){
        //console.log(eval(value));
        return eval(value); 
      }
    

    And call it in template like this:

    <div *ngIf="isVisible(question.visibility)">
            <label [attr.for]="question.key">{{question.label}}</label>
            <div [ngSwitch]="question.controlType">
                <input [name]="question.key" *ngSwitchCase="'textbox'" [formControlName]="question.key" [id]="question.key" [type]="question.type">
    
                <select [id]="question.key" *ngSwitchCase="'dropdown'" [formControlName]="question.key">
          <option *ngFor="let opt of question.options" [value]="opt.key">{{opt.value}}</option>
        </select>
            </div>
            <div class="errorMessage" *ngIf="!isValid">{{question.label}} is required</div>
        </div>
    

    Your json file will be like:

     ...
     new TextboxQuestion({
            key: 'firstName',
            label: 'First name',
            value: 'Bombasto',
            required: true,
            order: 1, 
            visibility: 'true'
          }),
    
          new TextboxQuestion({
            key: 'emailAddress',
            label: 'Email',
            type: 'email',
            order: 2,
            visibility: 'this.form.get("firstName").value ==="abc"'
          })
    

    visibility: 'this.form.get("firstName").value ==="abc"', as you can see you should write in json as usual in component class logic, because it will run in component context

    CODE EXAMPLE