8

I'm building a web form that is supposed to be dynamic.
When a user selects an option from a list, the next form inputs are generated based on his input.
For instance:

<mat-form-field>
     <mat-select placeholder="Type" [(ngModel)]="row.Type" (change)="TypeChosen(row.Type, row)">
         <mat-option [value]="0">Treatment</mat-option>
         <mat-option [value]="1">Travel</mat-option>
         <mat-option [value]="2">Medication</mat-option>
         <mat-option [value]="3">Equipment</mat-option>
     </mat-select>
</mat-form-field>

If he selects Type 'Treatment', he gets another selection input with some options with a few other inputs, and if he selects a different Type, he gets different options and other inputs.

I understand that I need to dynamically generate HTML content, and maybe a dynamic component.
What is the best approach to do this in an easy way?

5
  • dynamic component will do...because angular not allows to put dynamic html from your ts file (you can do that with domsanatizer) Commented Jun 13, 2018 at 8:29
  • 1
    Why don't you use *ngIf directive ? This is how dinamically html works in angular, with some other directives which they also include * in their syntax. Commented Jun 13, 2018 at 8:36
  • @PranayRana Since I'm not experienced, an example would help me. Thanks. Commented Jun 13, 2018 at 8:36
  • @Korte There are too many options and conditional flows, that *ngIf complicates the code and makes it messy. Commented Jun 13, 2018 at 8:37
  • I still would recommend using *ngIf combined with short functions that contain the conditions. Something like *ngIf="shouldIshowX()", with shouldIshowX() { return condition1 && condition2 && !condition3 } Commented Jun 23, 2018 at 19:46

2 Answers 2

8
+25

I'd suggest creating a component for each sub-form and then *ngIf them based on the selected option, like so:

<!-- component.html -->

<mat-form-field>
  <mat-select placeholder="Type" [(ngModel)]="row.Type" (change)="onTypeChosen(row.Type, row)">
    <mat-option [value]="0">Treatment</mat-option>
    <mat-option [value]="1">Travel</mat-option>
    <mat-option [value]="2">Medication</mat-option>
    <mat-option [value]="3">Equipment</mat-option>
  </mat-select>
</mat-form-field>

<my-treatment-component *ngIf="type === 0" [someInput]="'some value'"></my-treatment-component>
<my-travel-component *ngIf="type === 1" [somethingElse]="true"></my-travel-component>
<my-medication-component *ngIf="type === 2" (someOutput)="onMedicationOutput($event)"></my-medication-component>
<my-equipment-component *ngIf="type === 3"></my-equipment-component>

If you already have something holding your Type selection, you can bind that to the *ngIfs instead. If not, create a field in your controller class and hold the selected type in there.

// component.ts

public type: number | null = null;

public onTypeChosen(type: number, row): void {
  this.type = type;
}

If your sub-forms have parts that are re-usable (or are basically the same, sans configuration), it's generally a good practice to extract the re-usable code into components in and of themselves and compose them together.

Hope this helps a little :-)

Sign up to request clarification or add additional context in comments.

Comments

3

To Add the options dynamically, angular provide ( *ngFor ).

<mat-form-field>
     <mat-select placeholder="Type" [(ngModel)]="row.Type" (change)="TypeChosen(row.Type, row)" *ngFor="let option of options; let i = index">
         <mat-option (click)="updateOptions(option)" [value]="{{i}}">option.text</mat-option>
     </mat-select>
</mat-form-field> 

in your controller .ts

private options = [];

private initOptions(){
this.options = [
{text:'Treatment' , possibleOptionsRelates:[text:'possible1']},
{text:'Travel' , possibleOptionsRelates:[text:'possible12']},
{text:'Medication' , possibleOptionsRelates:[text:'possible13']}];
}
private updateOptions(option){
     this.options.push(...option.possibleOptionsRelates);
}

3 Comments

Thanks. It's a good start, but it's more complicated than that, because I'm not adding only one mat-select with options, but a few other inputs, which some are added for Treatment, some for Travel etc.
are other mat-select sharing the same options ??
No. Each has it's own condition and options.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.