7

I want to redirect to the another page & focus should be on the some DIV with id let's say 'some-div-id'. I tried following

$location.path('/' + $scope.config_path.school + '/' +
        $routeParams.someUrl + '/#some-div-id')

This is working fine but it first change # to %23 Like

/%23some-div-id  #If '#' is not already present in the URL
/%23some-div-id#some-div-id #If '#' is laready present in the URL
/#some-div-id

I also tried following

$location.path('/' + $scope.config_path.school + '/' +
        $routeParams.someUrl + '/').hash('some-div-id')

it is creating a proper URL but not scroll down to the DIV with id some-div-id

EDITED

app.run(function($rootScope, $location, $anchorScroll, $routeParams) {
  $rootScope.$on('$routeChangeSuccess', function(newRoute, oldRoute) {
    setTimeout(function() {
      if ($location.hash()) {
        $anchorScroll($location.hash());
      }
    });
  });
})

app.controller('MainCntrl', function($scope, $location, $anchorScroll, $routeParams) {
});

Also i tried $location.path & $location.url

Salil
  • 46,566
  • 21
  • 122
  • 156
  • try using `$anchorScroll` https://docs.angularjs.org/api/ng/service/$anchorScroll#!/ – Claies Sep 09 '15 at 06:21
  • @Claies I have tried `$anchorScroll` but it is not scroll down to the DIV, may be bacuase i am redirecting from one page to other and then using `$anchorScroll` – Salil Sep 09 '15 at 08:01
  • I've done a bit of research and I don't think you can redirect from one angular app to an anchor tag in another angular app, since the app that the anchor tag is in has to be the one to all the `$anchorScroll` service. – Claies Sep 17 '15 at 11:55
  • Why not have a directive on the root element of the page that checks what's in the url, finds the div and focuses it? That way you could just some-div-id without the # . – sirrocco Sep 23 '15 at 10:10

5 Answers5

7

Try using $location.url instead of $location.path .

As per the documentation , $location.path only changes the path whereas $location.url changes the path, search and hash.

So the code would be like

$scope.goto = function() {
    $location.url('pageone#one');
};

Where pageone is URL of the state and #one is the ID

Also to make it work when directly visiting the URL with the ID in it , use $anchorScroll . On the $stateChangeSuccess event , checking weather $location.hash is present or not.If present , then call $anchorScroll . The code would look like

.run(function($rootScope, $location, $anchorScroll,$timeout) {
    $rootScope.$on('$stateChangeSuccess',
        function(event, toState, toParams, fromState, fromParams) {
            $timeout(function() {
                if ($location.hash()) {
                $anchorScroll();
               }
          });
    });
})

Example - http://plnkr.co/edit/4kJjiMJImNzwLjRriiVR?p=preview ( For seeing change in URL check http://run.plnkr.co/plunks/4kJjiMJImNzwLjRriiVR/#/pageone )

Prayag Verma
  • 5,581
  • 3
  • 30
  • 56
  • @Salil the plunkr works on Chrome 45. In case there is confusion about the demo , the main purpose of it was to go to http://run.plnkr.co/plunks/4kJjiMJImNzwLjRriiVR/#/pagetwo first and then via clicking on the links there redirect to http://run.plnkr.co/plunks/4kJjiMJImNzwLjRriiVR/#/pageone#one . In case it still doesn't work could share some information about which browser you might be using or what part of the demo is not working for you and I would be willing to help – Prayag Verma Sep 23 '15 at 07:57
  • Please check my Edited Answer – Salil Sep 23 '15 at 09:38
  • @Salil , a question I had , Are using ng-route or ui-router ? This is important because if you are using ng-route then the $routeChangeSuccess ( https://docs.angularjs.org/api/ngRoute/service/$route#$routeChangeSuccess ) is the event to callback fired after successful transition and if you are using then ui-router then $stateChangeSuccess (https://github.com/angular-ui/ui-router/wiki#state-change-events) is the event fired when state transition is complete. – Prayag Verma Sep 23 '15 at 11:01
  • @Salil I have created a new [Plnkr](http://plnkr.co/edit/E11e9m?p=preview) which uses ng-route instead of ui-router and $routeChangeSuccess callback , check demo at http://run.plnkr.co/plunks/E11e9m/#/pageone – Prayag Verma Sep 23 '15 at 11:30
  • Try using $timeout method instead of setTimeout and see if that makes a difference. One thing as the code in the above plnkr is working without issue , could you create a plnkr of your code , so that it is easy to debug – Prayag Verma Sep 23 '15 at 14:00
2

This behavior is expected. Angular will not allow a second # in your url by default, thus every # beyond the first one will be escaped, resulting in %23 which is the escape character for #: http://www.w3schools.com/tags/ref_urlencode.asp.

You could try enabling html5mode by adding the following to your .config block:

$locationProvider.html5Mode({
    enabled: true
});

If that doesn't solve your problem, or if you need to support support IE8, your best bet would probably be to use $anchorScroll().

Here's the documentation.

In your app, you could pass the id of the div you want to scroll to as a parameter in your url (using $routeParams or ui-router's $stateParams), and then call a function that will scroll to that div immediately on page load, such as:

$scope.scrollTo = function(id) {
   $location.hash(id);
   $anchorScroll();
}

Please also read the following for a more detailed explanation on how to use $anchorScroll() for your specific problem:

How to handle anchor hash linking in AngularJS

Namely, this particular section:

Set up your angular routing as usual, then just add the following code.

app.run(function($rootScope, $location, $anchorScroll, $routeParams) {
  //when the route is changed scroll to the proper element.
  $rootScope.$on('$routeChangeSuccess', function(newRoute, oldRoute) {
    $location.hash($routeParams.scrollTo);
    $anchorScroll();  
  });
});

and your link would look like this:

<a href="#/test?scrollTo=foo">Test/Foo</a>
Community
  • 1
  • 1
Tiago
  • 4,233
  • 13
  • 46
  • 70
2

$location.path(page);

just add the dependency in ur controller by add $location, This method redirects you on this route, without any error.

Dinesh Jain
  • 149
  • 11
2

In ng-book, there is something about %13 signs replacing normal letter. Unfortunately, it's about different topic - it is about an $http or xhr api call through REST, where there are two modes ( same would be here ) - one normal mode and second JQuery like. It turned out that jquery adds these %13 signs to things like arr[]=1.

Why i am saying this? Because after solution comes libraries and functions which support marginal conditions.

The situation in Your question is quite simple. There is $location service, which is solution and urls are created simillary in two modes, which are hashbang and not hashbang.

In problem with jquery parameters, developers provided library for exchanging jquery parameters to normal. There are many converters in real life, like pdf to doc etc.

Please look at short chapter in this book.

It is stated that in html5 mode, you cannot have two hashes in url, but in hashbang mode you can. Browser cannot know which hash is to go to in hashbang mode. The support for this is anchorScroll service.

I haven't checked if this works in this case but try to configure your app with AnchorScrollProvider:

.config(function($anchorScrollProvider){
    $anchorScrollProvider.disableAutoScrolling();
});

Then as i written, you can inject $anchorService service to any place in your app ( especially in controller binded to view containing some-div-id div ) And call anchorScroll() function of this service at any chosen time.

I cannot test it right now so this is theoretical answer.

changtung
  • 1,614
  • 15
  • 19
2

I had the same problem before and this post helped me out. Let's hope it is going to help you aswell, if it doesn't let me know so I can help you find another solution.

Good luck.

Community
  • 1
  • 1
RiesvGeffen
  • 1,539
  • 2
  • 11
  • 29