Home > database >  Add <a>-tag behavior to <tr>-tag (Angular)
Add <a>-tag behavior to <tr>-tag (Angular)

Time:09-06

does someone know how to make a html -row with a routerlink clickable, with the option to open it in the same tab OR a new tab (ctrl click). The problem that I encountered is, that you can't wrap the 'tr'-tag in a 'a'-tag. Thanks for any suggestions.

<tbody *ngFor="let item of defaultInvoicesList?._embedded.items">
                        <tr [routerLink]="this.getDetailsPath(item.legacyInvoiceId)" role="link">
                            <td>{{item.locationName}}</td>
                            <td>{{item.customerName}}</td>
                            <td><a [routerLink]="[getOrderDetailsUri(item.orderNumber)]">{{item.orderNumber}}</a></td>
                            <td>{{item.invoiceNumber}}</td>
                            <td>{{item.invoicePeriodStart | date: 'dd.MM.yyyy' }} - {{item.invoicePeriodEnd | date: 'dd.MM.yyyy' }}</td>
                            <td>{{item.createdByLastName}}, {{item.createdByFirstName}}</td>
                        </tr>
</tbody>

CodePudding user response:

You can do something like this, although when you ctrl click, it both navigates and opens in new tab, but you can eliminate that with a few tweaks!

ts

import {
  Component,
  Input,
  ChangeDetectionStrategy,
  ViewEncapsulation,
  Output,
  EventEmitter,
} from '@angular/core';
import { Router } from '@angular/router';

import { Config } from './config';
import { DataTable } from './data';
import { PageRequest } from './pageRequest';

@Component({
  selector: 'my-table',
  templateUrl: 'table.component.html',
  styleUrls: ['table.component.css'],
  changeDetection: ChangeDetectionStrategy.OnPush,
  encapsulation: ViewEncapsulation.None,
})
export class MyTableComponent {
  constructor(private router: Router) {}
  @Input()
  public config: Config;

  @Input()
  public data: DataTable<any>;

  public size = 5;
  public pageNumber = 0;

  @Output()
  public newPage: EventEmitter<PageRequest> = new EventEmitter<PageRequest>();

  @Output()
  public selection: EventEmitter<number> = new EventEmitter<number>();

  public changePage(pageNum: number) {
    const num =
      pageNum < 0
        ? 0
        : pageNum >= this.data.lastPage
        ? this.data.lastPage - 1
        : pageNum;

    this.pageNumber = num;

    this.newPage.emit({
      page: num,
      size: Number(this.size),
    });
  }

  public onSelect(index: number) {
    this.selection.emit(index   this.pageNumber * this.size);
  }

  emulateHref(link, event) {
    event.preventDefault();
    console.log(event);
    this.router.navigate([link]).then((result) => {
      if (event.ctrlKey) {
        window.open(window.location.href, '_blank');
      }
    });
  }
}

html

<table >
  <thead >
    <tr>
      <th *ngFor="let column of config">{{ column.header }}</th>
    </tr>
  </thead>
  <tbody >
    <tr
      my-active
      *ngFor="let row of data.data; index as rowIndex"
      (click)="emulateHref('details/'   rowIndex, $event)"
    >
      <td
        *ngFor="let column of config; index as i"
        [ngClass]="{ last: i === config.length - 1 }"
      >
        {{ row[column.value] }}
      </td>
    </tr>
  </tbody>
</table>
<div >
  <button type="button"  (click)="changePage(0)"><<</button>
  <button
    type="button"
    
    (click)="changePage(this.pageNumber - 1)"
  >
    <
  </button>
  <select
    
    [(ngModel)]="size"
    (change)="changePage(this.pageNumber)"
  >
    <option selected value="5">5</option>
    <option value="10">10</option>
    <option value="15">15</option>
  </select>
  <button
    type="button"
    
    (click)="changePage(this.pageNumber   1)"
  >
    >
  </button>
  <button
    type="button"
    
    (click)="changePage(this.data.lastPage)"
  >
    >>
  </button>
</div>

forked stackblitz

CodePudding user response:

    <tbody *ngFor="let item of defaultInvoicesList?._embedded.items">
        <a href="">
            <tr [routerLink]="this.getDetailsPath(item.legacyInvoiceId)" role="link">
                <td>{{item.locationName}}</td>
                <td>{{item.customerName}}</td>
                <td><a [routerLink]="[getOrderDetailsUri(item.orderNumber)]">{{item.orderNumber}}</a></td>
                <td>{{item.invoiceNumber}}</td>
                <td>{{item.invoicePeriodStart | date: 'dd.MM.yyyy' }} - {{item.invoicePeriodEnd | date: 'dd.MM.yyyy' }}
                </td>
                <td>{{item.createdByLastName}}, {{item.createdByFirstName}}</td>
            </tr>
        </a>
    </tbody>

CodePudding user response:

With the help of @naren-murali answer, I was able to find a solution. Just add a click-event to the 'tr'-element. That what it contains:

Ts:

emulateHref(link, event) {
        event.preventDefault();
        if (event.ctrlKey) {
            window.open(link, '_blank');
        } else {
            window.open(link, "_self")
        }
    }

HTML:

<tbody *ngFor="let item of defaultInvoicesList?._embedded.items">
                        <tr (click)="this.emulateHref(this.getDetailsPath(item.legacyInvoiceId), $event)">
                            <td>{{item.locationName}}</td>
                            <td>{{item.customerName}}</td>
                            <td><a [routerLink]="[getOrderDetailsUri(item.orderNumber)]">{{item.orderNumber}}</a></td>
                            <td>{{item.invoiceNumber}}</td>
                            <td>{{item.invoicePeriodStart | date: 'dd.MM.yyyy' }} - {{item.invoicePeriodEnd | date: 'dd.MM.yyyy' }}</td>
                            <td>{{item.createdByLastName}}, {{item.createdByFirstName}}</td>
                        </tr>
                        </tbody>

  • Related