href overrides ng-click in Angular.js
Asked Answered
L

17

123

When both, href and ng-click attributes are defined:

<a href="#" ng-click="logout()">Sign out</a>

the href attribute takes precedence over ng-click.

I am looking for a way to raise priority of ng-click.

href is required for Twitter Bootstrap, I can't remove it.

Lalise answered 18/2, 2013 at 15:10 Comment(5)
Could you elaborate on "href is required for Twitter Bootstrap"? Which part of it? CSS or JavaScript?Monroe
The Twitter Bootstrap nav "widget" is setup to use links, if you add a button to it, even one that's styled to look like a link it breaks the styling of the navigation. It's probably not semantic HTML but @sketchfemme's solution does what I (and probably Paul) want it to do.Swisher
Ignore everything I said, navbar works perfectly with buttons if you use the right HTML and classes. getbootstrap.com/components/#navbarSwisher
You should accept the answer by Mithu, which is to use an empty URLBargainbasement
@Lalise The original poster asked how to get a <a href> to not navigate. The accepted answer says to switch to a button. Although that works it is not the solution to the problem, especially if like myself you are forced to use <a href> because it's a bootstrap menu or something. The correct solution to this specific question is to use an empty url <a href="" ng-click="whatever()">Log out</a> - I tested it and can confirm it works. Thankfully someone else provided the correct answer or I'd still be stuck.Bargainbasement
W
36

You should probably just use a button tag if you don't need a uri.

Winy answered 18/2, 2013 at 15:18 Comment(3)
Yes, if you can elaborate on how Twitter Bootstrap requires it, maybe I can help more.Winy
How does this work with search engines? I am using AngularJS routing and need to maintain state in a service so for all of my internal application links I use $location, but removing href make it impossible for search engines to follow along the site.Goshen
buttons can't have other element inside them, so for styling, you wouldn't want to do that - if you need things inside of it.Barogram
P
246

This example from the angular documentation site just does href without even assigning it to an empty string:

[<a href ng-click="colors.splice($index, 1)">X</a>]

http://docs.angularjs.org/api/ng.directive:select

Psychomotor answered 26/8, 2013 at 18:6 Comment(5)
When I try this all of the links appear to be visited, which is not the behaviour I'm after. The other way (href="#") causes a page reload, which is also wrong.Eminent
This makes IE9 not to show a hand cursor. Using href="" solves it.Irk
@juampy, the hand over the link can be handled with CSS. This answer given is the official AngularJS way to do it.Poison
The # will get treated like hash link.Barogram
<a href="javscript:void(0)" ng-click="logout()">Sign out</a> will serve you well tooGreeson
S
90

You can simply prevent the default behavior of the click event directly in your template.

<a href="#" ng-click="$event.preventDefault();logout()" />

Per the angular documentation,

Directives like ngClick and ngFocus expose a $event object within the scope of that expression.

Sabra answered 18/9, 2014 at 22:35 Comment(6)
This is a great solution. If you have an href, you can right click to open it in a new tab, but on left click it calls ng-click. Exactly what I was looking forSpot
Once again an excellent answer. Both left and right click workAretha
Worked great for allowing Bootstrap carousel controls without triggering routing. Thanks!Thermosetting
Perfect! I can continue with links and get more index in Google and use ng-click to call in Ajax. Thanks.Midinette
Great solution, quick and useful. Thanks!Substantial
You saved me.. Thanks a lot.Guttapercha
H
74

Here is another solution :

<a href="" ng-click="logout()">Sign out</a>

i.e. Just remove the # from the href attribute

Headcloth answered 3/4, 2013 at 18:7 Comment(3)
For the question asked, this should be the solution. Worked on Angular 1.1.5 as wellButterscotch
It seems <a href="" ng-click=""> will prevent the ng-click in Android 2.3.x browser. I finally use <a href="javascript:void(0)" ng-click="">Douro
Duckegg's suggestion is the best oneIgnoramus
W
36

You should probably just use a button tag if you don't need a uri.

Winy answered 18/2, 2013 at 15:18 Comment(3)
Yes, if you can elaborate on how Twitter Bootstrap requires it, maybe I can help more.Winy
How does this work with search engines? I am using AngularJS routing and need to maintain state in a service so for all of my internal application links I use $location, but removing href make it impossible for search engines to follow along the site.Goshen
buttons can't have other element inside them, so for styling, you wouldn't want to do that - if you need things inside of it.Barogram
L
28

Just one more hint. If you need real URL (to support browser accessibility) you can do the following:

template:

<a ng-href="{{link}}" ng-click="$event.preventDefault(); linkClicked(link)">{{link}}</a>

directive:

$scope.linkClicked = function(link){
    // your code here
    $location.path(link);
};

In this way your code in linkClicked() will have chance to execute before navigating to the link

Levorotation answered 18/11, 2014 at 23:22 Comment(1)
This solution works and only changes the left click behaviour, right click stays intact (context menu), including the possibility to a link in href. So that is a more general solution compared to TooMuchTenacious, which actually answers the question more directly.Staten
E
22

In Angular, <a>s are directives. As such, if you have an empty href or no href, Angular will call event.preventDefault.

From the source:

    element.on('click', function(event){
      // if we have no href url, then don't navigate anywhere.
      if (!element.attr(href)) {
        event.preventDefault();
      }
    });

Here's a plnkr demonstrating the missing href scenario.

Epigraphy answered 16/10, 2014 at 15:7 Comment(0)
S
14

This worked for me in IE 9 and AngularJS v1.0.7:

<a href="javascript:void(0)" ng-click="logout()">Logout</a>

Thanks to duckeggs' comment for the working solution!

Shamefaced answered 24/9, 2014 at 20:25 Comment(1)
Works, the link doesn't change your url and isn't marked as visited. Best answer!Tunisia
R
13

There are so many answers for this question here but it seems there is a bit of confusion about what's actually going on here.

Firstly, your premise

"href overrides ng-click in Angular.js"

is wrong. What is actually happening is that after your click, the click event is first handled by angular(defined by ng-click directive in angular 1.x and click in angular 2.x+) and then it continues to propagate(which eventually triggers the browser to navigate to the url defined with href attribute).(See this for more about event propagation in javascript)

If you want to avoid this, then you should cancel the event propagation using the The Event interface's preventDefault() method:

<a href="#" ng-click="$event.preventDefault();logout()" />

(This is pure javascript functionality and nothing to do with angular)

Now, this will already solve your problem but this is not the optimal solution. Angular, rightfully, promotes the MVC pattern. With this solution, your html template is mixed with the javascript logic. You should try to avoid this as much as possible and put your logic into your angular controller. So a better way would be

<a href="#" ng-click="logout($event)" />

And in your logout() method:

logout($event) {
   $event.preventDefault();
   ...
}

Now the click event will not reach the browser, so it will not try to load the link pointed by href. (However note that if the user right clicks on the link and directly opens the link, then there won't be a click event at all. Instead it will directly load the url pointed by the href attribute.)

Regarding the comments about visited link color in the browsers. Again this has nothing to do with angular, if your href="..." points to a visited url by your browser by default the link color will be different. This is controlled by CSS :visited Selector, you can modify your css to override this behaviour:

a {
   color:pink;
}

PS1:

Some answers suggest to use:

<a href .../>

href is an angular directive. When your template is processed by angular this will be converted to

<a href="" .../>

Those two ways are essentially the same.

Riocard answered 19/12, 2017 at 17:1 Comment(0)
P
5

Just write ng-click before href ..It worked for me

<!DOCTYPE html>
<html>

  <head>
    <script data-require="[email protected]" data-semver="1.5.0" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.0/angular.js"></script>
    <script>
    angular.module("module",[])
.controller("controller",function($scope){
  
  $scope.func =function(){
    console.log("d");
  }
  
})</script>
  </head>

  <body ng-app="module" ng-controller="controller">
    <h1>Hello ..</h1>
    <a ng-click="func()" href="someplace.html">Take me there</a>
  </body>

</html>
Pase answered 8/3, 2017 at 9:20 Comment(0)
B
2

I don't think you need to remove "#" from href. Following works with Angularjs 1.2.10

<a href="#/" ng-click="logout()">Logout</a>
Burck answered 11/2, 2014 at 19:22 Comment(0)
B
1

You can also try this:

<div ng-init="myVar = 'www.thesoftdesign'">
        <h1>Tutorials</h1>
        <p>Go to <a ng-href="{{myVar}}">{{myVar}}</a> to learn!</p>
</div>
Bridget answered 27/4, 2018 at 10:26 Comment(0)
P
0

I'll add for you an example that work for me and you can change it as you want.

I add the bellow code inside my controller.

     $scope.showNumberFct = function(){
        alert("Work!!!!");
     }

and for my view page I add the bellow code.

<a  href="" ng-model="showNumber" ng-click="showNumberFct()" ng-init="showNumber = false" >Click Me!!!</a>
Postman answered 17/5, 2015 at 14:22 Comment(0)
S
0

Did you try redirecting inside the logout function itself? For example, say your logout function is as follows

$scope.logout = function()
{
  $scope.userSession = undefined;
  window.location = "http://www.yoursite.com/#"
}

Then you can just have

<a ng-click="logout()">Sign out</a>
Sheba answered 14/7, 2016 at 10:13 Comment(0)
D
0

Please check this

<a href="#" ng-click="logout(event)">Logout</a>

 $scope.logout = function(event)


 {
event.preventDefault();
alert("working..");
}
Dorton answered 27/9, 2016 at 15:16 Comment(0)
M
0
//for dynamic elements - if you want it in ng-repeat do below code

angular.forEach($scope.data, function(value, key) {
     //add new value to object
    value.new_url  = "your url";
});

 <div ng-repeat="row in data"><a ng-href="{{ row.url_content }}"></a></div>
Motorize answered 31/1, 2017 at 10:26 Comment(0)
M
0

This works for me

<a href (click)="logout()">
   <i class="icon-power-off"></i>
   Logout
</a>
Melisa answered 7/6, 2019 at 5:14 Comment(0)
G
0
 <a href="#">
       <span ng-click="logout()"> Sign out </span>
 </a>

I did like this and it worked for me.

Gunfight answered 10/6, 2021 at 6:54 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.