0

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);
       }
     }
2
  • Hi ! Did you tried (click)="buttonClicked($event) ? Commented Jul 16, 2020 at 16:18
  • Hi @yanesof__ I did try that and doesn't do anything. Thanks though. Commented Jul 16, 2020 at 16:25

1 Answer 1

1

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]();
}
Sign up to request clarification or add additional context in comments.

1 Comment

Thank you for the reply. I am currently handling it with a switch to determine what was clicked. If that is a sound way of doing it I'll keep it and go with that. I do like your idea on storing it in an object, kind of cool way of doing it. I'll keep this up a little longer to see who else opines.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.