0

I'm trying to create a custom drop-down cascading component using angular reactive form .

problem is, how to change 'state' drop-down box option(s) on country drop-down value change.

This part of the app.component.html

 <mat-sidenav-container class="example-container">       
  <mat-sidenav-content>
    <div class="module-menu"></div>
    <div class="container">
      <dynamic-form [fields]="regConfig" (submit)="submit($event)"> </dynamic-form>
    </div>
  </mat-sidenav-content>
</mat-sidenav-container>

This part of the app.component.ts

 regConfig: FieldConfig[] = [

    {
      type: "select",
      label: "Country",
      name: "country",
      value: "UK",
      options: ["India", "UAE", "UK", "US"]
    },
    {
      type: "select",
      label: "State",
      name: "state",
      options: []
    }

This part of the dynamic-form.component.ts

@Component({
  exportAs: "dynamicForm",
  selector: "dynamic-form",
  template: `       
  <form class="dynamic-form" [formGroup]="form" (submit)="onSubmit($event)" *ngIf="!controlTypeIsTable">
  <ng-container *ngFor="let field of fields;" dynamicField [field]="field" [group]="form">
  </ng-container>
  </form>
  <section *ngIf="controlTypeIsTable">
  <ng-container dynamicTable name="table" [table]="table" >  </ng-container>
  </section>
  `,
  styles: []
})
export class DynamicFormComponent implements OnInit {

  controlTypeIsTable: boolean
  @Input() fields: FieldConfig[] = [];
  @Output() submit: EventEmitter<any> = new EventEmitter<any>();


 ngOnInit() {
    if (field.type === "select") {
      control.valueChanges.subscribe((newValue: any) => {
        this.dropdownChange(newValue,'state')
      });
    }
  }

dropdownChange(value: any, targetControlName) { 
    this.form.get(targetControlName).setValue(value)
    //this.cd.detectChanges();
  }

This part of the select.component.ts

@Component({
  selector: "app-select",
  template: `<mat-form-field [formGroup]="group">
          <mat-select [placeholder]="field.label" [formControlName]="field.name">
          <mat-option *ngFor="let item of field.options" [value]="item">{{item}}</mat-option>
          </mat-select>
          </mat-form-field>`,
  styles: []
})
export class SelectComponent implements OnInit {
  field: FieldConfig;
  group: FormGroup;
  constructor() {}
  ngOnInit() {}
}

enter image description here

1 Answer 1

1

html

<select class="form-control selectState" (change)="selectcontry($event.target.value)" name="contry required>
    <option *ngFor="let contry of regConfig" [value]="contry.options">{{contry.value}}</option>
</select>

<select class="form-control selectState" (change)="selectState($event.target.value)" name="state" required>
     <option *ngFor="let state of contry" [value]="state">{{state}}</option>
</select>

.ts File

export class AppComponent {
  // City Names
  contry: any = [];
  regConfig = [
    {
      type: "select",
      label: "Country",
      name: "country",
      value: "UK",
      options: ["state1", "state2", "state3", "state4"]
    },
    {
      type: "select",
      label: "State",
      value: "india",
      options: ["state5", "state6", "state7"]
    },
    {
      type: "select",
      label: "State",
      value: "USA",
      options: ["state8", "state9", "state10"]
    }
  ];
  constructor() {}
  selectcontry(e) {
    this.contry = e;
    this.contry = e.split(",");
    console.log(this.contry);
  }
  selectState(e) {
    console.log(e);
  }
}

try this way, I have changed the structure of the json.and try this Demo

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

4 Comments

Thanks for your response. it is good for template driven forms approach. i am unable to add options to state drop-down control. here json is being used to create dynamic element.on country value change event, update state drop-down options dynamically ( calling same rest api) .
in my approach everything is working fine but options are not reflecting on state drop-down control
can you create a stackbliz demo? by hardcoded rest responses?
if you change [value]="contry.options" to [value]="contry.value" you will gate the contry name in selectcontry(e){ }. then you can fire a rest call and give the array to this.contry. it will populate

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.