Search code examples
angularjstimeranchorroute-provideranchor-scroll

How do I set a timer in AngularJS to scroll to an element ID if URL contains parameter of x?


How do I set a timer for AngularJS to scroll to an ID if the URL contains parameter? By the way the URL is external therefore it is not from my website.

Here's my problem:

1. User clicks on word 'See Today's Sale' with url as www.mySite.com/#/index#today from an email in Outlook (emphasizing that it's from an external link therefore I cannot place href, etc or edit <a> tag because there is no html/it is external.

2. When they click on the outlook link it goes to www.mySite.com/#/index and deletes the #today. Therefore will not scroll down to where #today is.

3. When they go back to outlook and click on the link again, the #today works and is not deleted. It will also scroll down to where it is. The site has to be visited for it to work.

I searched the internet and they still do not have any solutions for external links, the ones I saw are for in-site solutions where they edit their <a> tags.

I've tried these below but none of them worked:

Sol'n 1

*other routeProviders here*
...
$routeProvider.when('/index', {
        templateUrl: 'app/views/index.htm'
    });

$routeProvider.otherwise({ redirectTo: '/index#today' });

But the # only becomes %23 or is deleted

Sol'n 2

I've also tried this scrollTo:

app.directive('scrollto',
    function ($anchorScroll, $location) {
        return {
            link: function (scope, element, attrs) {
                element.click(function (e) {
                    e.preventDefault();
                    $location.hash(attrs["scrollto"]);
                    $anchorScroll();
                });
            }
        };
    })

and changed the link in outlook to www.mySite.com/#/index?scrollTo=today but forgot that the scrollTo is an attribute therefore it's supposed to be placed in the <a> tag, am i right? But we're using external links so we can't edit anything in outlook except for their add link feature.

Sol'n 3

Lastly I've tried this too:

...
$routeProvider.when('/index', {
        controller: 'myCtrl',
        templateUrl: 'app/views/index.htm'
    });
...

app.run(function ($rootScope, $location, $anchorScroll, $timeout) {
    $rootScope.$on("$routeChangeSuccess", function (event, next, current) {
        if ($location.hash()) {
            $timeout(function () { $anchorScroll() }, 5);
        } else {
            window.scrollTo(0, 0);
        }
    });
});

app.controller('myCtrl', ['$scope', '$location', '$anchorScroll',
    function ($scope, $location, $anchorScroll) {
        $scope.gotoBottom = function () {
            $location.hash('today');
            $anchorScroll();
        };
    }]);

But it doesn't work. (Still the same, still need to double click)

To be Sol'n 4

So I thought maybe I could:

  1. Manually place a parameter in the outlook link: example: www.mySite.com/#/index?scrollMe=today

  2. Retrieve that parameter that was manually typed into the url box or manually typed in outlook email's url.

  3. And then maybe add a timer like 2 seconds or 1 second to scroll to the ID of the parameter which is today after the page loads.

The purpose of the timer is maybe the autoscroll won't work because the page haven't loaded yet and it was already scrolling? Probably not but I'd like to be sure on the timer part so I'd have it wait for a second before scrolling at least. A second is not gonna hurt anyone I think. I could also lower it to milliseconds but the timer is only for testing.

I'm really new to AngularJS and I'd really like to ask you, the seniors and experts, if there are any work-around for this. :(

Cheers!


Solution

  • You can use $routeParams So it will be something like this -

    $routeProvider.when('/index/:when', {
       controller: 'myCtrl',
       templateUrl: 'app/views/index.html'
    });
    
    app.controller('myCtrl', ['$scope', '$routeParams', '$location', '$anchorScroll'
        function ($scope, $routeParams, $location, $anchorScroll) {
            var goToId = $routeParams.when;
            $location.hash(goToId);
            $anchorScroll();
        }]);
    

    My index.html has this

    <div id="today" style="margin-top: 2000px;">
      This div shows today's contents
    </div>
    

    Finally the url should be like this /#/index/today or /#/index/yesterday

    AngularJS Docs for reference - https://docs.angularjs.org/tutorial/step_09