I have buttons that I need to add for a toolbar and I can't seem to properly add a click event to them without it feeling like a hack.
Here is how I setup/return my buttons:
export class ImportButtons {
getButtons(): ButtonItem[] {
return [new ButtonItem({
group: 'imports',
section: 'admin',
name: 'Approve',
class: 'btn btn-primary approve-all-button',
text: 'Approve',
hasMenu: true,
menuClass: 'approve-all-menu',
subItems: [new SubItem({ value: 'Approve All' })]
}),
new ButtonItem({
group: 'imports',
section: 'admin',
name: 'OnHold',
class: 'btn btn-primary on-hold-button',
text: 'On Hold',
hasMenu: true,
menuClass: 'on-hold-menu',
subItems: [new SubItem({ value: 'On Hold All' }),
new SubItem({ value: 'Revert from On Hold' }),
new SubItem({ value: 'Revert All from On Hold' })]
})
];
}
}
This is in my html that grabs these and displays them:
<agc class="btn-group dropdown drop-button-container" ngbdropdown="" placement="bottom-right" ng-reflect-placement="bottom-right">
<ng-container *ngFor="let buttons of this.fillTable('import', 'admin')">
<ng-container *ngIf="buttons.hasMenu === true">
<button class="{{buttons.class}}" type="button" (click)="buttonClicked( buttons );" > {{buttons.text}} </button>
<button aria-haspopup="true" class="btn btn-primary dropdown-toggle dropdown-toggle-split admin-split-button icon-fa-caret-down" data-toggle="dropdown" ngbdropdowntoggle="" type="button" aria-expanded="false"></button>
<ng-container *ngFor="let sub of buttons.subItems">
<agc class="dropdown-menu" ngbdropdownmenu="">
<span class="dropdown-item c-pointer" (click)="buttonClicked( buttons, sub )" >{{sub.value}}</span>
</agc>
</ng-container>
</ng-container>
</ng-container>
</agc>
I currently tried calling a method when clicked ('buttonClicked()') where it tells me what was clicked. But when I click a button I see the rest of the buttons blink as if it was doing a PostBack. Because of this it feels like a hack.
Is there a correct way of doing this? Each button added will have it's own method to call when clicked (obviously) and I couldn't find a way to use a string in the click event.
For instance I initially had in my button class a 'click' property where I would put the method name to call - so "click = 'onHoldClick($event)'" and the html click would look like "(click)='{{ buttons.click}}'" but it didn't like that.
the html iterates through the buttons it grabs from method 'fillTable' and it looks like this:
fillTable(groupName: string, section: string): ButtonItem[] {
switch (this.page.currentPage) {
case 'imports':
return this.importButtons.getButtons().filter(n => n.section === section);
case 'export':
return this.exportButtons.getButtons().filter(n => n.section === section);
case 'sales':
return this.salesButtons.getButtons().filter(n => n.section === section);
case 'bom':
return this.bomButtons.getButtons().filter(n => n.section === section);
}
}
I think that the problem is in the *ngFor when you use a function. I suggest use an auxiliar variable
this.buttonsActual=this.fillTable('import', 'admin');
//and make the *ngFor using
<ng-container *ngFor="let buttons of buttonsActual">
You can try also use trackBy
BTW, your idea is correct (click)="buttonClicked(button)"
. Well, you can pass only the button.name or whatever. Then you has two aproach, use a large switch in the function
buttonClicked(button)
{
switch (button.name)
{
case "...":
break;
case "...":
break;
...
}
}
Or store in an object the diferrencs functions
command={
one:this.function1
two:this.function2
}
function1(){..}
function2(){..}
//and in buttonClicked
buttonClicked(button)
{
command[button.name]();
}