Attaching click to anchor tag in angular

266.8k views Asked by At

I am trying to attach click event to anchor tags (coming from ajax) and block the default redirection. How can I do it in angular ?

<ul>
    <li><a href="/abc"><p>abc</p></a></li>
    <li><a href="/abc1"><p>abc1</p></a></li>
    <li><a href="/abc2"><p>abc2</p></a></li>
    <li><a href="/abc3"><p>abc3</p></a></li>
</ul>

In ts file:

constructor(elementRef: ElementRef, renderer: Renderer) { 
    this.listenFunc = renderer.listen(elementRef.nativeElement, 'click', (event) => {
        event.preventDefault();
        let target = event.target || event.srcElement || event.currentTarget;
        console.log(target);
    });  
}

This will attach event to all elements, how can I limit this to anchor tag only ?

All helps appreciated.

16

There are 16 answers

6
PatrickW On

I think you are not letting Angular work for you.

In angular 2:

  1. Remove the href tag from <a> to prevent a page forwarding.
  2. Then just add your usual Angular click attribute and function.
  3. Add to style: "cursor: pointer" to make it act like a button
1
aungye On

<a href="javascript:void(0);" (click)="onGoToPage2()">Go to Page 2</a>

7
Vicky On

You can use routerLink (which is an alternative of href for angular 2+) with click event as below to prevent from page reloading

<a [routerLink]="" (click)="onGoToPage2()">Go to page</a>
3
Francisco d'Anconia On

I had to combine several of the answers to get a working solution.

This solution will:

  • Style the link with the appropriate 'a' styles.
  • Call the desired function.
  • Not navigate to http://mySite/#

    <a href="#" (click)="!!functionToCall()">Link</a>

2
Andrew Landsverk On

You just need to add !! before your click method handler call: (click)="!!onGoToPage2()". The !! will prevent the default action from happening by converting the return of your method to a boolean. If it's a void method, then this will become false.

1
Alexei - check Codidact On

I have encountered this issue in Angular 5 which still followed the link. The solution was to have the function return false in order to prevent the page being refreshed:

html

<a href="" (click)="openChangePasswordForm()">Change expired password</a>

ts

openChangePasswordForm(): boolean {
  console.log("openChangePasswordForm called!");
  return false;
}
1
Mario B On

While the question is technically already answered I think all answers here forget something important: Just adding a click-handler is not enough. You also want the link to be usable for people who only use the keyboard for Accessibility reasons. Usually this means that hitting Enter while focussing the element should have the same effect as clicking on it. While we're at it we could also set the role. If the link is actually used as a button we should set role="button" - this way screenreaders will announce it as a button and not a navigation-link. For the original problem: Almost all answers here seem to work for me, but i chose the one with the empty routerLink - I think it makes it semantically clear that no navigation is wanted. Other solutions could lead to confusions later (lets say someone reads your code in a year).

<a [routerLink]="" (click)="doSomething()" (keyup.enter)="doSomething()" role="button" tabindex="0">your link</a>
5
Neutrino On
<a href="#" (click)="onGoToPage2()">Go to page 2</a>
0
Naheed Shareef On

I have examined all the above answer's, We just need to implement two things to work it as expected.

Step - 1: Add the (click) event in the anchor tag in the HTML page and remove the href=" " as its explicitly for navigating to external links, Instead use routerLink = " " which helps in navigating views.

<ul>
  <li><a routerLink="" (click)="hitAnchor1($event)"><p>Click One</p></a></li>
  <li><a routerLink="" (click)="hitAnchor2($event)"><p>Click Two</p></a></li>
</ul>

Step - 2: Call the above function to attach the click event to anchor tags (coming from ajax) in the .ts file,

  hitAnchor1(e){
      console.log("Events", e);
      alert("You have clicked the anchor-1 tag");
   }
  hitAnchor2(e){
      console.log("Events", e);
      alert("You have clicked the anchor-2 tag");
   }

That's all. It work's as expected. I created the example below, You can have a look:-

https://stackblitz.com/edit/angular-yn6q6t

2
BlueCaret On

I've been able to get this to work by simply using [routerLink]="[]". The square brackets inside the quotes is important. No need to prevent default actions in the method or anything. This seems to be similar to the "!!" method but without needing to add that unclear syntax to the start of your method.

So your full anchor tag would look like this:

<a [routerLink]="[]" (click)="clickMethod()">Your Link</a>

Just make sure your method works correctly or else you might end up refreshing the page instead and it gets very confusing on what is actually wrong!

0
Gaspar On

You can try something like this:

<a href="javascript: void(0);" (click)="method()">

OR

<a href="javascript: void(0);" [routerLink]="['/abc']">
0
Pierre On

Clean way to handle anchor tags and href and keeping your anchor styling:

html:

Pass in the $event on click

<a href (click)="doSomething($event)">Do something</a>

Typescript:

Get the event as MouseEvent and call e.preventDefault()

doSomething(e: MouseEvent): void {
    e.preventDefault();

    //Do something
}

Your styling will stay in tact and no default browser anchor handling will take place.

0
Zaid Pathan On

This worked for me:

<a class="btn-link" (click)="clickedFunction()">Click me</a>
0
Jaimin Patel On

I was able to implement this successfully

<a [routerLink]="['/login']">abc</a>
0
Samim Ahmed On

You can use routerLink which is an alternative of href for angular 2.** Use routerLink as below in html

<a routerLink="/dashboard">My Link</a>

and make sure you register your routerLink in modules.ts or router.ts like this

const routes: Routes = [
  { path: 'dashboard', component: DashboardComponent }
]
0
Mike Dalrymple On

I had issues with the page reloading but was able to avoid that with routerlink=".":

<a routerLink="." (click)="myFunction()">My Function</a>

I received inspiration from the Angular Material docs on buttons: https://material.angular.io/components/button/examples

UPDATE I've started using routerLink="" since Angular 12. I was finding that routerLink="." was routing me to a parent page.