Clint William Theron
Clint William Theron

Reputation: 155

How to pass argument in PrimeNG's SplitButton?

This is my MenuItem array:

this.ButtonItems = [
  {label: 'Edit', icon: 'fa fa-pencil-alt', command: (x) => {
      this.onEditDocument(x);
  }},
  {label: 'Duplicate', icon: 'pi pi-times', command: (x) => {
      this.onDuplicate(x);
  }}
];

Both functions need a parameter of type string (item.id).

Here is my template:

<p-splitButton 
    label="Save" 
    icon="i-btn fa fa-search" 
    title="View document"
    (onClick)="onViewDocument(item.id)" 
    [model]="ButtonItems(item.id)"></p-splitButton>

The code doesn't compile. I was trying to follow this example but I don't understand it. How can I get this right?

UPDATE:

My splitbutton is next to each item in the following table:

<p-table 
    [value]="currentDocuments" 
    [responsive]="true" 
    [columns]="cols" 
    [paginator]="true" 
    [rows]="10" 
    [showCurrentPageReport]="true" 
    styleClass="p-datatable-responsive-demo" 
    currentPageReportTemplate="Showing {first} to {last} of {totalRecords} entries">
    <ng-template pTemplate="header" let-columns>
        <tr>
            <th *ngFor="let col of columns">
                <div class="header-no-overflow">{{col.header}}</div>
            </th>
            <th style="width: 60px;"></th>            
        </tr>
    </ng-template>
    <ng-template pTemplate="body" let-item let-columns="columns">
        <tr>
            <td *ngFor="let col of columns" >
                <span class="p-column-title">{{col.header}}</span>
                <div *ngIf="col.type != 'File Uploader'">
                    {{item[col.field]}}
                </div>
                <div *ngIf="col.type == 'File Uploader'">
                    <div *ngFor="let file of item[col.field]">
                        <a [href]="file.downloadUrl" target="_blank">{{file.name}} </a>
                    </div>
                </div>
            </td>
            <td>
                <ng-container *ngFor="let buttonItem of ButtonItems">
                    <p-splitButton 
                        label="Save" 
                        icon="i-btn fa fa-search" 
                        title="View document"
                        (onClick)="onViewDocument(item.id)" 
                        [model]="buttonItem(item.id)"
                    ></p-splitButton>
                </ng-container>
            </td>
        </tr>
    </ng-template>
</p-table>

I added this here to explain my scenario in more detail.

My MenuItem looks like so:

this.ButtonItems = [
      [{ label: 'Edit', icon: 'fa fa-pencil-alt', command: (x: string) => this.onEditDocument(x) }],
      [{ label: 'Duplicate', icon: 'pi pi-times', command: (x: string) => this.onDuplicateDocument(x) }]
    ];

I want to add split buttons on each of the items in the table. The two buttons (edit and duplicate should be moved to items in the splitbutton. Here is a image to illustrate what i mean: image of table that should contain splitbuttons for eac item

Upvotes: 3

Views: 4545

Answers (4)

Hamid
Hamid

Reputation: 908

I gave a try to others solution but they didn't work! so I have to find my own workaround for resolving this problem. Here is the thing, the split-button has two events "onClick" & "onDropdownClick", the second event will be triggered before executing the command function of button options! so I'm setting my wished value on that event (I mean onDropDownClick) and then when I'm calling the command function I have that value. take a look at my code, and u definitely better understand what I'm talking about.

 <p-splitButton
                class="w-100"
                [label]="'SHARED.EDIT' | translate"
                [title]="'PRODUCTS.EDIT_PRODUCT' | translate"
                icon="pi pi-eye"
                (onClick)="editProduct(item.id)"
                [model]="recordMenuItems"
                (onDropdownClick)="handleActionsClick(item)"
              >
              </p-splitButton>

 public selectedProductForExecutingAction: any = null;

  public handleActionsClick(product) {
    this.selectedProductForExecutingAction = product;
  }

  public recordMenuItems: MenuItem[] = [
    {
      label: 'Copy',
      icon: 'pi pi-copy',
      command: (event) => {
        this.copy(this.selectedProductForExecutingAction.id);
      }
    },
    {
      label: 'Delete Product',
      icon: 'pi pi-times',
      command: (event) => {
        this.deleteProduct(this.selectedProductForExecutingAction);
      }
    }
  ];

Upvotes: 4

jlgranda
jlgranda

Reputation: 689

Esto es más claro para mí.

xxx.html
<p-splitButton icon="pi pi-print" label="Imprimir"
(onClick)="imprimirFactura(rowData)" [model]="cmds(rowData)"></p-splitButton>
//xxx.componente.ts
    cmds(row): any {
        const items = [
            {
                label: 'Acción 1', 
                icon: 'pi pi-clone', command: () => {
                    this.dummy(row);
                }
            },
            {
                label: 'Acción 2', 
                icon: 'pi pi-clone', command: () => {
                    this.confirmarPagoFactura(row);
                }
            },
        ];
        return items; (x); }}];   
    }

Upvotes: 1

Clint William Theron
Clint William Theron

Reputation: 155

So with my specific scenario here is the solution:

template:

<td>
        <p-splitButton appendTo="body" label="Save" icon="pi pi-check" (onClick)="onViewDocument(item.id)" [model]="buttonActions[item.id]"></p-splitButton>
</td>

.ts:

buttonActions: {[id:string]: MenuItem[]} = {};  
  
this.currentDocuments.forEach(el => {
  this.buttonActions[el.id as string] = [
    {label: 'View', icon: 'pi pi-refresh', command: () => {
        this.onViewDocument(el.id as string);
    }},
    {label: 'Edit', icon: 'pi pi-times', command: () => {
        this.onEditDocument(el.id as string);
    }},

];
})
  

Upvotes: 3

Barremian
Barremian

Reputation: 31105

In the linked example, the property model is bound to a function which is actually a bad idea. In a default change detection strategy setup, the function might get invoked for each change detection cycle.

In your case you might have to iterate over the ButtonItems array.

<ng-container *ngFor="let buttonItem of ButtonItems">
  <p-splitButton 
    label="Save" 
    icon="i-btn fa fa-search" 
    title="View document"
    (onClick)="onViewDocument(item.id)" 
    [model]="buttonItem"
  ></p-splitButton>
</ng-container>

Update

Each menu item needs to be an array instead of an object.

this.ButtonItems = [
  [{ label: 'Edit', icon: 'fa fa-pencil-alt', command: (x) => this.onEditDocument(x) }],
  [{ label: 'Duplicate', icon: 'pi pi-times', command: (x) => this.onDuplicate(x) }]
];

Upvotes: 1

Related Questions