3

I have multiple (any number) dropdowns on the form that i need to build dynamically.

All these must have a value selected, so need to apply required validator.

Sample json

  [
    {
      "FeatureCaption": "Style",
      "SelectedValue": "shaker",
      "FeatureList": [
        {
          "FeatureId": "CHOOSE",
          "FeatureName": "Choose",
          "IsSelected": true
        },
        {
          "FeatureId": "shaker",
          "FeatureName": "Shaker",
          "IsSelected": false
        }
      ]
    },
    {
      "FeatureCaption": "Material",
      "SelectedValue": "std",
      "FeatureList": [
        {
          "FeatureId": "CHOOSE",
          "FeatureName": "Choose",
          "IsSelected": true
        },
        {
          "FeatureId": "std",
          "FeatureName": "Standard",
          "IsSelected": false
        }
      ]
    }
  ]

These features are available on the form via this.features

Component code to get data and to build form

  onInit() {

    //init form, so angular will complain about formgroup since template is going first
    this.inItForm();

    this.dataSubscription = this.projectSubService.getProjectSubConfig(this.subId).subscribe(
      res => {
        this.features = res.Features;

        //push in features
        this.pushInFormFeatures();
      },
      error => {
        //do error handling part...
      }
    );

  }

inItForm method

  inItForm() {
    //will be putting the config as FormArray
    let configFeatures = new FormArray([]);

    //loop through the features and push into configFeatures FormArray above
    //this.features.forEach(i =>
    //  configFeatures.push(
    //    new FormGroup({
    //      'config': new FormControl({ value: i.SelectedValue, options: i.FeatureList, label: i.FeatureCaption }, Validators.required)
    //    })
    //  )
    //);

    //now create the main FormGroup and add config features to it
    this.projectForm = new FormGroup({
      'features': configFeatures
    });
  }

Push in form features method

  pushInFormFeatures() {
    this.features.forEach(i =>
      (<FormArray>this.projectForm.get('features')).push(
        new FormGroup({
          'config': new FormControl({ value: i.SelectedValue, options: i.FeatureList, label: i.FeatureCaption }, Validators.required)
        })
      )
    );
  }

and html

  <form [formGroup]="projectForm" (ngSubmit)="onSubmit()">

      <div class="form-row">
        <div class="col">

          <div formArrayName="features">

            <div class="form-group form-row" *ngFor="let ic of projectForm.get('features'); let i=index;" [formGroupName]="i">
              <div class="col-lg-2 text-right"><label for="{{i}}" class="col-form-label">{{ic.label}} <app-required-star></app-required-star></label></div>
              <div class="col-lg-10">
                <select class="form-control" id="{{i}}" formControlName="config" [appAutoFocus]="">
                  <!--<option *ngFor="let op of ic.options" [value]="op.FeatureId">{{op.FeatureName}}</option>-->
                </select>
                <!--<span class="mwk-validation-error form-text" *ngIf="!projectForm.get('features')[{{i}}].valid && projectForm.get('features')[{{i}}].errors?.required">Required</span>-->
              </div>
            </div>

          </div>

        </div>
     </div>


    <button type="submit" class="btn btn-primary btn-sm">Submit</button>

  </form>

I am getting following error

    ERROR Error: "Cannot find a differ supporting object '[object Object]' 
of type 'object'. NgFor only supports binding to Iterables such as Arrays."

Obviously i am not building the formArray properly including select options.

How can i build some thing like this? I have been looking for an example and haven't been able to find one to use.

Update 1

For now using template driven approach till i figure out how to do above

  <form (ngSubmit)="onSubmit(f)" #f="ngForm">

    <div class="form-group form-row" *ngFor="let f of features; let i=index;">
      <div class="col-lg-2 text-right"><label for="{{f.FeatureId}}" class="col-form-label">{{f.FeatureCaption}} <app-required-star></app-required-star></label></div>
      <div class="col-lg-10">
        <!--custom-select-->
        <select class="form-control" id="{{f.FeatureId}}" name="{{f.FeatureId}}" [appAutoFocus]="i === 0" ngModel required>
          <option  value="" selected>Choose...</option>
          <option *ngFor="let fl of f.FeatureList" [value]="fl.FeatureId" [selected]="fl.IsSelected">{{fl.FeatureName}}</option>
        </select>
      </div>
    </div>


    <div class="row mt-2">
      <div class="col-lg-2 text-right">&nbsp;</div>
      <div class="col-lg-10">

        <button type="submit" class="btn btn-primary btn-sm" [disabled]="!f.valid">Submit</button>

      </div>
    </div>

  </form>
2
  • Any luck with this? Commented Jan 29, 2019 at 23:37
  • Never got the chance to get back to it. Commented Jan 30, 2019 at 14:56

0

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.