html5Mode + <a href=""> + <base href> causing unintended reload

2,728 views
Skip to first unread message

Christopher Chase

unread,
Jul 31, 2012, 9:13:31 AM7/31/12
to ang...@googlegroups.com
I have a problem where a blank href in an anchor performs the ng-click function and is still redirecting me to the base href of my app. 

<a href="" ng-click="myFunction()">link 1</a>

I'm using html5Mode and have a <base href="/app/">

Here's a link to reproducing the problem against angular-seed. https://github.com/cfchase/angular-basehref-anchor

I'm following the instructions for ngHref which say this should not cause a reload.  Perhaps I'm routing incorrectly or there's a better way.  I posted a comment on angular issue 1102, but since that is legacy browser related, I figured I'd post here to see if anyone had any ideas or know of an existing issue I missed before submitting a ticket separately.

Thanks for any help,

Chris

Gopal Patel

unread,
Jul 31, 2012, 10:13:25 AM7/31/12
to ang...@googlegroups.com
just guessing, but does your function returns false ?

--
You received this message because you are subscribed to the Google Groups "AngularJS" group.
To post to this group, send email to ang...@googlegroups.com.
To unsubscribe from this group, send email to angular+u...@googlegroups.com.
Visit this group at http://groups.google.com/group/angular?hl=en.
 
 

Christopher Chase

unread,
Jul 31, 2012, 10:52:33 AM7/31/12
to ang...@googlegroups.com
For the project I forked from angular-seed to reproduce, I just used the documented code from the ngHref docs, so it looks like: 

<input ng-model="value"/><br/>
<a id="link-1" href ng-click="value = 1">link 1</a> (link, don't reload)<br/>
<a id="link-2" href="" ng-click="value = 2">link 2</a> (link, don't reload)<br/>
<a id="link-3" ng-href="/{{'123'}}">link 3</a> (link, reload!)<br/>
<a id="link-4" href="" name="xx" ng-click="value = 4">anchor</a> (link, don't reload)<br/>
<a id="link-5" name="xxx" ng-click="value = 5">anchor</a> (no link)<br/>
<a id="link-6" ng-href="{{value}}">link</a> (link, change location)

The ones with hrefs link properly, the ones without an href redirect to base.  It works fine in normal mode, and then breaks as soon as I turn on html5Mode with the base href.  I have two commits in there, one with normal routing and one with html5Mode. Changing it to ng-click="true" or ng-click="false" both still redirect to the base ref.

In my actual app, returning false or true from the function similarly has no impact.

Anthony Bullard

unread,
Aug 1, 2012, 11:28:38 PM8/1/12
to ang...@googlegroups.com
Maybe I'm not seeing the whole issue, but in your own example, why even have the href attribute if it is null?  Does removing the empty hrefs solve the problem?

Christopher Chase

unread,
Aug 2, 2012, 10:57:06 AM8/2/12
to ang...@googlegroups.com
The documentation in the angular.js explains it pretty well (pasted below).  Removing the href (like link 5 in the previously posted example code) should work, which is just the ng-click, but not redirect.  This all works fine with normal routing, however, it breaks for me when using html5Mode.  I have found an ugly workaround by using href="javascript:;".   However, the workaround is less than ideal.  It seems like a bug, and I guess I'll submit it. 

/*
 * Modifies the default behavior of html A tag, so that the default action is prevented when href
 * attribute is empty.
 *
 * The reasoning for this change is to allow easy creation of action links with `ngClick` directive
 * without changing the location or causing page reloads, e.g.:
 * <a href="" ng-click="model.$save()">Save</a>
 */
var htmlAnchorDirective = valueFn({
  restrict: 'E',
  compile: function(element, attr) {
    // turn <a href ng-click="..">link</a> into a link in IE
    // but only if it doesn't have name attribute, in which case it's an anchor
    if (!attr.href) {
      attr.$set('href', '');
    }

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

On Wednesday, August 1, 2012 11:28:38 PM UTC-4, Anthony Bullard wrote:
Maybe I'm not seeing the whole issue, but in your own example, why even have the href attribute if it is null?  Does removing the empty hrefs solve the problem?

swein...@gmail.com

unread,
Aug 14, 2012, 5:02:15 PM8/14/12
to ang...@googlegroups.com
I am having this same issue - your ugly workaround does the trick but it's....ugly.

Eric Jain

unread,
Aug 15, 2012, 11:23:38 PM8/15/12
to ang...@googlegroups.com
On Thursday, August 2, 2012 7:57:06 AM UTC-7, Christopher Chase wrote:
The documentation in the angular.js explains it pretty well (pasted below).  Removing the href (like link 5 in the previously posted example code) should work, which is just the ng-click, but not redirect.  This all works fine with normal routing, however, it breaks for me when using html5Mode.  I have found an ugly workaround by using href="javascript:;".   However, the workaround is less than ideal.  It seems like a bug, and I guess I'll submit it.

I just ran into something like this while testing an app on an older iPhone.

The following link (note the missing "href") reloads the page instead of executing foo():

  <a data-ng-click="foo()">...</a>

Adding a "javascript:" href appears to fix the problem:

  <a data-ng-click="foo()" href="javascript:">...</a>

Not using html5 mode or setting a base URL...

I there an issue for this, meanwhile?

Christopher Chase

unread,
Aug 15, 2012, 11:30:12 PM8/15/12
to ang...@googlegroups.com
I created issue 1225.

https://github.com/angular/angular.js/issues/1225

Doesn't look like it's gotten any attention yet, though.

Dylan Greene

unread,
Nov 20, 2012, 2:36:43 PM11/20/12
to ang...@googlegroups.com
I'm alo seeing this issue. It doesn't reload the page but it goes to the base url which is basically the same thing.

Michel Rasschaert

unread,
Feb 27, 2013, 3:58:23 PM2/27/13
to ang...@googlegroups.com
Same causes (html5 mode routing, a and base href) are causing the same effects for me (redirects to base href) with angular.js 1.0.5

The workaround of using href="javascript:" worked for me.

I have tried to understand the issue but I'm not seeing anything strange. The angular anchor directive intercepts the click events as it should and calls preventDefault() as specified in the docs.
Reply all
Reply to author
Forward
0 new messages