35

I dynamically loop thru tabs and i would like to add a (click) event on to be able to load different options when i select tab.

Isn't it possible to have an event (click) event on ? I tried with (selectChange) on but then i cannot get hold of bank.id from my loop when creating tabs.

Isn't it possible to add simple click event on dynamically created tabs??

    <mat-tab-group>
  <mat-tab label="All transactions">
    <mat-list>
      <mat-list-item *ngFor="let bank of banks">
        <h4 mat-line>{{bank.fullName}}</h4>
      </mat-list-item>
    </mat-list>
  </mat-tab>
  <mat-tab *ngFor="let bank of banks" (click)="fetchAccounts(bank.id)" label="{{bank.fullName}}">

    <mat-list>

      <mat-list-item *ngFor="let account of accounts">
        <h4 mat-line>{{bank2.fullName}}</h4>
      </mat-list-item>
    </mat-list>
  </mat-tab>
  <!-- <mat-tab label="Test Bank" disabled>
    No content
  </mat-tab> -->

</mat-tab-group>
MrWeiland
  • 459
  • 1
  • 5
  • 14

5 Answers5

76

Isn't it possible to add simple click event on dynamically created tabs? - no i think, it isn't possible, but you can use (selectedTabChange) on <mat-tab-group> as:

<mat-tab-group (selectedTabChange)="yourFn($event)">

The event-Object holds an index, so you can do something like this:

yourFn($event){
    this.fetchAccounts(this.banks[$event.index].id)
}

Example: https://stackblitz.com/edit/angular-xurhan

enno.void
  • 6,242
  • 4
  • 25
  • 42
  • How to pass value through yourFn(item) ? – Hikaru Shindo Jun 19 '20 at 14:17
  • The problem with this is when you refresh the entire page it goes into the selected tab function, even if you didn't manually click the tab. So if you want the tabs to reopen after refreshing and it remember which tab you were on, you can't use (selectedTabChange). I had the last selected tab in local storage but this is getting overwritten when I refresh the page, because it goes in this function whenever you refresh. – Collin Feb 25 '22 at 20:34
  • @CollinFox maybe a hacky workaround would be flag variable whichs been checked in selectedTabChange, and restore value from localstorage if it was a "fake" (from page refresh) selection – enno.void Feb 28 '22 at 08:16
  • my solution ended up being to make the tab text label fill the whole tab by setting its height manually to 48px, removed the default left and right padding on the mat tab label and added my own padding in my custom tab label div, and after doing so I made the text tab label div have a (click) trigger to call my onTabChanged() function. This way I was able to tell if the user really clicked on the tab or not – Collin Mar 04 '22 at 18:44
  • so I have
    {{labelName}}
    – Collin Mar 04 '22 at 18:53
  • (So basically Mario Skrlec's answer below, but with padding & custom height on the div to make it fill the whole tab label) – Collin Mar 04 '22 at 19:00
  • I needed to get the value used for the label of the tab when handling the event. Using Firefox's web developer tools, I found it to be at: `event['tab']['textLabel']`. – waterproofpatch Mar 07 '23 at 04:55
17

I don't have the same problem as you had. All I needed was a simple click event on a mat-tab. I change the route on a click event but the click event did not bind to the tab. I did some research and what you can do is create a custom label on which you can put the click event. For example...

<mat-tab>
    <ng-template mat-tab-label>
        <span (click)="onClick()">Custom label</span>
    </ng-template>
</mat-tab>

This will work if you create the tab dynamically. To expand on your example...

<mat-tab *ngFor="let i of [1, 2, 3]">
    <ng-template mat-tab-label>
        <span (click)="onClick()">Custom label {{i}}</span>
    </ng-template>
</mat-tab>

The only problem I had was with the css for the span. It doesn't have any padding so you actually have to click on the span itself to make the event work. If you click outside it but within the tab, the tab is going to change but the event won't fire.

To fix that, make the padding bigger on this span. For example,

.custom-label { padding: 15px 0 15px 0; }

This one, for example worked for me but there was still room on the left and right side that the click didn't wan't to fire. I din't solve that one.

Mario Škrlec
  • 305
  • 4
  • 7
  • 2
    I found a better workaround. Set the `.custom-label` padding with a value greater than the tab area (50px seems enough), and set it as `position: absolute`. The click will trigger in the whole tab. – undefined is our god Jan 23 '20 at 21:37
0

use [selectedIndex] to set dynamically loop thru

0
                    <tr *ngFor="let objTransaction of arrBankTransaction; index as i;">
                    <td>{{objTransaction.BankTransactionDate | date: 'dd MMM yyyy'}}</td>
                    <td>{{objTransaction.BankTransactionCategoryName}}</td> 
                    <td>{{objTransaction.BankTransactionName}}</td>
                    <td>{{objTransaction.BankTransactionDescription}}</td>
                    <td class="text-end">
                        <div class="text-success" *ngIf="objTransaction.BankTransactionTypeName === 'Credit'">{{objTransaction.BankTransactionAmount | currency:"GBP":"symbol"}}</div>
                        <div class="text-danger" *ngIf="objTransaction.BankTransactionTypeName === 'Debit'">{{objTransaction.BankTransactionAmount | currency:"GBP":"symbol"}}</div>
                    </td>
                    <td class="text-end">
                        <div *ngIf="i <= 0">
                            <div class="text-success" *ngIf="objTransaction.BankTransactionTypeName === 'Credit'">{{objTransaction.BankTransactionAmount | currency:"GBP":"symbol"}}</div>
                            <div class="text-danger" *ngIf="objTransaction.BankTransactionTypeName === 'Debit'">{{objTransaction.BankTransactionAmount | currency:"GBP":"symbol"}}</div>
                        </div>
                        <div *ngIf="i > 0">
                            <div class="text-success" *ngIf="arrBankTransaction[i - 1].BankTransactionAmount + objTransaction.BankTransactionAmount > 0">{{arrBankTransaction[i - 1].BankTransactionAmount + objTransaction.BankTransactionAmount  | currency:"GBP":"symbol"}}</div>
                            <div class="text-warning" *ngIf="arrBankTransaction[i - 1].BankTransactionAmount + objTransaction.BankTransactionAmount == 0">{{arrBankTransaction[i - 1].BankTransactionAmount + objTransaction.BankTransactionAmount  | currency:"GBP":"symbol"}}</div>                                
                            <div class="text-danger" *ngIf="arrBankTransaction[i - 1].BankTransactionAmount + objTransaction.BankTransactionAmount < 0">{{arrBankTransaction[i - 1].BankTransactionAmount + objTransaction.BankTransactionAmount  | currency:"GBP":"symbol"}}</div>                                
                        </div>
                    </td>
                    <td class="text-center"><div *ngIf="objTransaction.StatusID === 1"><i class="bi bi-toggle-on text-success"></i></div><div *ngIf="objTransaction.StatusID === 0"><i class="bi bi-toggle-off text-warning"></i></div></td>
                    <td class="text-center"><a href="/admin/bank-transaction/{{objTransaction.BankTransactionID}}/edit/" title="Edit"><i class="bi bi-pencil"></i></a></td>
                    <td class="text-center"><a href="/admin/bank-transaction/{{objTransaction.BankTransactionID}}/delete/" title="Delete"><i class="bi bi-trash"></i></a></td>
                </tr>
Simon
  • 1
  • 1
    As it’s currently written, your answer is unclear. Please [edit] to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Jul 31 '23 at 13:07
-1

The problem is not the mat-tab. The problem is that the value you are trying to pass to MatTabGroup is contained within MatList. For example, if you did:

<h4 mat-line (click)="getValue(bank)">{{bank.fullName}}</h4>
getValue(value: string) {
  console.log(value);
}

That would work. Since you need to get the value from within TabGroup, basically you would have to do what Mr. Void said.

David Anthony Acosta
  • 4,766
  • 1
  • 19
  • 19