0

I am making angular application with angular dynamic form where i am using ng-select library.

The HTML with select:

    <div *ngFor="let question of questions" class="form-row {{question.class}}">
            <ng-container *ngIf="question.children">
                <div [formArrayName]="question.key" class="w-100">
                    <div *ngFor="let item of form.get(question.key).controls; let i=index" [formGroupName]="i" class="row mt-1">
                        <div *ngFor="let item of question.children" class="{{item.class}} align-middle">
                            <div class="w-100">
                                <dynamic-form-builder [question]="item" [index]="i" [form]="form.get(question.key).at(i)"></dynamic-form-builder>
                            </div>
                        </div>
                    </div>
                    <div class="container">
                        <div class="row">
                            <div class="col-6 col-sm-12 col-lg-6 col-md-6">
                                <div class="form-label-group" *ngIf="showTemplateDropdown">
                                    <ngi-select placeholder="Select Template" [required]="true" [hideSelected]="false" [multiple]="true" [items]="templateList"
                                     dropdownPosition="down" bindLabel="name" bindValue="id" (add)="getTemplateValues($event)" (remove)="onRemove($event)">
                                    </ngi-select>
                                </div>
                            </div>
                        </div>
                    </div>
                    <div class="container">
                        <div class="row">
                            <div class="col-6 col-sm-12 col-lg-6 col-md-6">

                            </div>
                            <div class="col-6 col-sm-12 col-lg-6 col-md-6 text-right">
                                <div class="btn-group  float-right">
                                    <button class="btn btn-primary btn-round btn-fab mat-raised-button" mat-min-fab="" mat-raised-button="" type="button"
                                     (click)="addControls('template_properties')">
                                        <span class="mat-button-wrapper"><i class="material-icons mt-2">add</i></span>
                                        <div class="mat-button-ripple mat-ripple" matripple=""></div>
                                        <div class="mat-button-focus-overlay"></div>
                                    </button> &nbsp;&nbsp;&nbsp;
                                    <button class="btn btn-primary btn-round btn-fab mat-raised-button" mat-min-fab="" mat-raised-button="" type="button"
                                     (click)="removeControls('template_properties')">
                                        <span class="mat-button-wrapper"><i class="material-icons mt-2">remove</i></span>
                                        <div class="mat-button-ripple mat-ripple" matripple=""></div>
                                        <div class="mat-button-focus-overlay"></div>
                                    </button>
                                </div>
                            </div>
                        </div>
                    </div>

                </div>
            </ng-container>
            <ng-container *ngIf="!question.children">
                <div class="w-100">
                    <dynamic-form-builder [question]="question" [form]="form"></dynamic-form-builder>
                </div>
            </ng-container>
        </div>

Here the [items]="templateList" has the following,

[{"id":"5bebba2c20ccc52871509d56","name":"Template One"},
{"id":"5bebba5720ccc52871509d57","name":"Template Two"},
{"id":"5bebba8d20ccc52871509d5d","name":"Template Three"}]

I am having (change)="getTemplateValues($event)" event for detecting each change happen when we select an item from dropdown.

The change event function Edited,

    getTemplateValues(e) {
      this.dynamicFormService.getRest("url" + '/' + e.id").subscribe(res => {
  try {
    if (res.status === "true") {
      res.data.template_properties.forEach(element => {
        this.templateArray.push(element);
      });
      this.form = this.qcs.toFormGroup(this.questions);
      for (let i = 0; i < this.templateArray.length; i++) {
        this.addControls('template_properties');
      }
      let propertiesArray = [];
      this.templateArray.forEach(element => {
        propertiesArray.push(element);
      });
      this.form.patchValue({
        'template_properties': propertiesArray
      });
    } else {

    }
  }
  catch (error) {

  }
})

}

console.log(this.propertiesArray) gives the following,

[{"property_name":"Property one","property_type":4,"property_required":true,"property_origin":1},{"property_name":"Property one","property_type":5,"property_required":true,"property_origin":1}]  

In the below image i have deleted template three but the template three properties still showing in it..

enter image description here

Here first i am filtering the data first and ignoring the duplicates and each time i am sending the newly selected values alone to the service and fetching the data related to the id element.id.

And using this.addControls('template_properties') to make open the number of rows, and elements will get patched to the form template_properties.

this.form.patchValue({
 'template_properties': propertiesArray
});

As of now everything working fine..

The problem actually arise from here:

If we delete a selected list from dropdown, (say i have selected all three template and i have deleted the template two then that particular template's template_properties needs to get deleted..

I have tried with (remove)="onRemove($event)" but its not working because while remove data, the (change) function also calls..

How can i remove the template_properties with this.removeControls('template_properties'); of particular deleted template name in the change event or remove event..

Remove Function:

  onRemove(e) {
    console.log(e);
    this.dynamicFormService.getRest("url" + '/' + e.value.id").subscribe(res => {
      try {
        if (res.status === "true") {
          for (let i = 0; i < res.data.template_properties.length; i++) {
            this.removeControls('template_properties');
          }
        } else {

        }
      }
      catch (error) {

      }
    })
  }

Remove Control:

  removeControls(control: string) {
    let array = this.form.get(control) as FormArray;
    console.log(array)
    array.removeAt(array.length);
  }

console.log(array) gives,

enter image description here

Maniraj Murugan
  • 8,868
  • 20
  • 67
  • 116

1 Answers1

0

It should be pretty easy fix. Use (add) instead of (change) in ngi-select.

 onRemove(e) {
    console.log(e);
    this.dynamicFormService.getRest("url" + '/' + e.value.id").subscribe(res => {
      try {
        if (res.status === "true") {
          this.form = this.qcs.toFormGroup(this.questions);

          // Issue is here, you should remove only specific record
          // which is being passed from function `e`
          for (let i = 0; i < res.data.template_properties.length; i++) {
            this.removeControls('template_properties'); 
          }

          let propertiesArray = [];
          this.templateArray.forEach(element => {
            propertiesArray.push(element);
          });
          this.form.patchValue({
            'template_properties': propertiesArray
          });
        } else {

        }
      }
      catch (error) {

      }
    })
  }

Pass the index in removeControls where you want to remove the element from.

  removeControls(control: string, index:number) {
    let array = this.form.get(control) as FormArray;
    console.log(array)
    array.removeAt(index);
  }

console.log(array) gives, enter image description here

Maniraj Murugan
  • 8,868
  • 20
  • 67
  • 116
Sunil Singh
  • 11,001
  • 2
  • 27
  • 48
  • If i use like this, then in remove the entire ```template_properties``` is getting removed.. – Maniraj Murugan Nov 14 '18 at 07:44
  • It means, the logic of `onRemove` function is wrong. Share the code of `onRemove`. – Sunil Singh Nov 14 '18 at 07:45
  • Kindly see my updated code for remove.. If i am wrong kindly make me correct for remove function.. How to remove the removed item's (template name) ```template_properties```.. – Maniraj Murugan Nov 14 '18 at 07:48
  • Sunil, Also updated my getTemplateValues (add) function by removing the filter which shows error after implementing ```(add)``` .. Even now Its working for add but not for remove.. Kindly check whether ```removeControl('template_properties')``` is right one please.. – Maniraj Murugan Nov 14 '18 at 08:28
  • Updated the answer where could be the issue. Share your `removeControls` code as well. – Sunil Singh Nov 14 '18 at 08:33
  • Updated with removecontrol function at last in my question.. If any needed i can provide the code.. Kindly help me to fix it.. – Maniraj Murugan Nov 14 '18 at 08:38
  • Also if i give ```this.form = this.qcs.toFormGroup(this.questions); ``` this line inside onRemove function, then the entire data is getting removed.. (I hope its not needed in remove function) – Maniraj Murugan Nov 14 '18 at 08:39
  • Updated my remove function again (minimized).. Now its getting removed as per the count in that template if template one has one template_properties length then it gets deleted one at last, same way the template three has two properties and it deletes the last two properties instead of the two properties which is in the middle.. Say i have choosen template one,three,two and so three is in middle so the middle two properties (as three has two properties) needs to get removed but the last two (one from template three and one from template two is getting deleted.. – Maniraj Murugan Nov 14 '18 at 08:52
  • Share html code where you have` – Sunil Singh Nov 14 '18 at 09:00
  • I have give complete HTML that i use.. It may not be clear for you.. It was derived from this stackblitz https://stackblitz.com/edit/angular-x4a5b6-rrfv1b – Maniraj Murugan Nov 14 '18 at 09:20
  • you need to pass the `index` from `removeControls`. Updated the answer. Note : You may need to pass this index from html and `onRemove` function. – Sunil Singh Nov 14 '18 at 09:41
  • Do you mean to add like ```(remove)="onRemove($event,index)"```?? – Maniraj Murugan Nov 14 '18 at 09:44
  • Yes, you got it. – Sunil Singh Nov 14 '18 at 09:44
  • It gives the following, ```{"index":2,"label":"Template Three","value":{"id":"5bebba8d20ccc52871509d5d","name":"Template Three"},"htmlId":"ab33bc17cd61","selected":false} ``` When i delete the template three.. – Maniraj Murugan Nov 14 '18 at 09:54
  • and print the value of `array` index in `removeControls` function. – Sunil Singh Nov 14 '18 at 10:05
  • Sorry are you asking to do ```console.log(array)``` inside removecontrol function?? – Maniraj Murugan Nov 14 '18 at 10:18
  • yes, for this line `let array = this.form.get(control) as FormArray;` – Sunil Singh Nov 14 '18 at 10:19
  • If i am using, I have tried with ```for (let i = 0; i < res.data.template_properties.length; i++) { this.removeControls('template_properties', e.index); }```.. As ```console.log(e)``` has index value as i given you in previous comment.. It deletes correctly when we delete from last but if we delete from center only one item getting deleted and not the count the index has.. But deleting from last to first works.. – Maniraj Murugan Nov 14 '18 at 10:21
  • Sorry ignore my edit in your solution.. I have given screenshot of data comes from array in my question.. – Maniraj Murugan Nov 14 '18 at 10:41
  • Sunil, Whether this is a right approach, ```this.removeControls('template_properties', e.index);``` all the time its not helping to delete the right element?? – Maniraj Murugan Nov 14 '18 at 11:22