0

I have a PrimeNg p-tree

    <p-tree [value]="treeNodes" selectionMode="single" [(selection)]="selectedNode"></p-tree>

TreeNodes are expressed with ng-templates, one of the templates being as follows.

    <ng-template let-node pTemplate="stagebased" >
        <input [(ngModel)]="node.label" type="text"  >
        <p-dropdown [options]="stages"  [(ngModel)]="stage"  optionLabel="name"></p-dropdown>
   </ng-template>

There is a menu on the left which has a menu item with this command -

command: (event) => { this.addElement("<Node Label>", "stagebased") }

So you click a menu item and that calls addElement(label: string, type: string), which adds another TreeNode as a child of the root node. addElement is follows:

addElement(label: string, type: string) {
    var node =
    {
      label: label,
      type: type
    };
    this.selectedNode = this.treeNodes[0];
    this.selectedNode.children.push(node);
  }

All good so far -- you can click addElement multiple times to add multiple treeNodes containing input fields and dropdowns with the same select options available.

enter image description here

The problem is if I select an option in one dropdown - the other dropdown applies the same option selected. I cannot select a different option for one dropdown instance as opposed to another.

How do I express the ngModel on p-dropdown in a way that allows for multiple selected 'stage' items?

Thanks

anvw
  • 149
  • 3
  • 15

2 Answers2

1

You can bind [(ngModel)] to an array. Each dropdown needs to be bound to a separate model.

So something like:

[(ngModel)]="selectedStages[i]"

Where i is being incremented for each new dropdown.

You should be able to use something like the following to increment i:

<div *ngFor="let x of array; let i = index; trackBy:trackByIndex">
   control here
</div>

trackByIndex(index: number, obj: any): any { return index; }

let x of array here would be whatever your main loop is going to be.

Patrick
  • 5,526
  • 14
  • 64
  • 101
  • Yes -- thanks. I've been trying that. The problem was getting the incrementing happening eg with an *ngFor, when its within an ng-template. the dropdowns still seemed to pick up the same value when selected. But this should be on the right track. I will have to bind to a model eventually. – anvw Aug 14 '21 at 06:49
  • @anvw I have updated my answer with a possible solution for the incrementing index. – Patrick Aug 14 '21 at 14:52
  • 1
    Thanks Patrick, definitely the right answer -- I just have to work through it. cheers – anvw Aug 15 '21 at 23:50
0

Partly-there or substantially-there answer:

The trick seems to be not to use [(ngModel)] - which looks like it binds all the selected values to one thing. Rather, use an onChange event:

     <p-dropdown [options]="stages" appendTo="body" (onChange)="onChangeEvent($event.value)" optionLabel="name"></p-dropdown>

With something like

 onChangeEvent(stage: Stage) {
    console.log("stage.name = " + stage.name);
  }

So the onChange $event.value captures the selected value of each or any dropdown, rather than binding the values of all the dropdowns together

anvw
  • 149
  • 3
  • 15