Search code examples
angularangular2-templateangular2-formsangular-ngselect

Appending ng-select on button click


I am using ng2-select in my template for selecting the items, there is a button named "Add" which when click should show another select field with list of other categories of items. For this the simplest version of my code looks like this:

@Component({
moduleId: module.id,
selector: 'client-user-detail',
templateUrl: `<div #one> 
              <ng-select #selectRole [allowClear]="true" 
              [multiple]="true" (data)="refreshValue($event)" 
              (selected)="onSelectRole($event)"
              (removed)="removed($event)"
              (typed)="typed($event)"
              placeholder="Choose/Search">
             </ng-select>                                   

            <button [disabled]="isDisable"
                    class="btn btn-default" 
                    (click)="add()"> 
                    <i class=" fa fa-save"></i>
                      Add
            </button>


  `,
  styleUrls: ['clientuserdetail.component.css']
  })

   export class TestComponent {
   @ViewChild('selectRole') public select: SelectComponent;
   @ViewChild('one') d1:ElementRef;

    constructor(
    private renderer: Renderer
    ) { }

   add() {
   let htmlText = `<ng-select #selectRole [allowClear]="true" 
                [multiple]="true" (data)="refreshValue($event)" 
                (selected)="onSelectRole($event)"
                (removed)="removed($event)" (typed)="typed($event)" 
                placeholder="Choose/Search">
                </ng-select>`;

   this.renderer.invokeElementMethod
     (this.d1.nativeElement,'insertAdjacentHTML',
      ['beforeend',htmlText]);

    }

 }

The above code doesn't create a select field. I read somewhere about component Resolver can be useful in such circumstances but I didn't grasp clear way to use it. If there is anyone who can simply explain me about how this problem can be solved, I will be very grateful. I need a clear illustration about how the components can be dynamically added or appended in angular 2. Thank you in advance.


Solution

  • I'm not able to answer exactly with the way you are trying to add a field, I would recommend instead to put your ng-select inside an ngFor that your add() function would increment and remove all the viewChild.

    import { Component } from '@angular/core';
    /**
     * Created by lejendarm on 08/08/17.
     */
    
    
    class Role {
      id: number;
      label: string;
    
      /* I'm not sure about the need of a constructor */
      constructor() {
        this.id = 0;
        this.label = '';
      }
    }
    
    @Component({
      moduleId: module.id,
      selector: 'client-user-detail',
      template: `<div *ngFor="role in roles"> 
                  <ng-select [allowClear]="true" 
                  [multiple]="true" (data)="refreshValue($event, role)" 
                  (selected)="onSelectRole($event, role)"
                  (removed)="removed($event, role)"
                  (typed)="typed($event, role)"
                  placeholder="Choose/Search">
                 </ng-select>                                   
                </div>
                <button [disabled]="isDisable"
                        class="btn btn-default" 
                        (click)="add()"> 
                        <i class=" fa fa-save"></i>
                          Add
                </button>`,
      styleUrls: ['clientuserdetail.component.css']
    })
    export class TestComponent {
      private roles: Array<Role>;
    
      constructor(
      ) {
        this.roles = [new Role()];
      }
    
      add() {
        this.roles.push(new Role())
      }
    
      refreshValue($event, role) {}
      onSelectRole($event, role) {}
      removed($event, role) {}
      typed($event, role) {}
    }
    

    PS: Even if there is no direct link with your issue, I would use template instead of templateUrl and close the div #one to show a better code.