2

I'm using AngularUI Router with Bootstrap. I have two views within the same state, and want to scroll to the second view when a button is clicked. I don't need to do any scrolling when the initial state and views load. I want the page to scroll to #start when the "Add More" button is clicked. I've attempted to use $anchorScroll to accomplish this, but am not having any luck.

Any suggestions on a good way to accomplish this?

HTML:

<!-- index.html -->

<div ui-view="list"></div>
<div ui-view="selectionlist"></div>

<!-- list.html -->

 <div id="scrollArea"><a ng-click="gotoBottom()" class="btn btn-danger btn-lg" role="button">Add More</a>

<!-- selectionlist.html -->

<div class="row" id="start"></div>

Javascript for Controller:

myApp.controller('SelectionListCtrl', function (Selections, $location, $anchorScroll) {
    var selectionList = this;
    selectionList.selections = Selections;
    this.selectedServices = Selections;
    selectionList.gotoBottom = function() {

     $location.hash('start');
     $anchorScroll();
     };
  });

Javascript for Routes:

myApp.config(function ($stateProvider, $urlRouterProvider, $uiViewScrollProvider) {
    $uiViewScrollProvider.useAnchorScroll();

    $urlRouterProvider.otherwise('/');

    $stateProvider

      .state('selection', {
              url: '/selection',
              views: {
                  'list': {
                      templateUrl: 'views/list.html',
                      controller: 'ProjectListCtrl as projectList'
                  },
                  'selectionlist': {
                      templateUrl: 'views/selectionlist.html',
                      controller: 'SelectionListCtrl as selectionList'

                  }
              }
              })
Ken
  • 3,091
  • 12
  • 42
  • 69

1 Answers1

1

Yes, it is possible to autoscroll in AngularUI Router without changing states.


As mentionned previously in my comment, you need to call the scrolling function with an ng-click="gotoBottom()" instead of an ng-click="gotoSection()"

Also, the function definition gotoBottom() must be in the ProjectListCtrl, not in the SelectionListCtrl. This is because the call gotoBottom() happens in the list view:

'list': {
templateUrl: 'list.html',
controller: 'ProjectListCtrl as projectList'
}

As gotoBottom() is called from the list.html view, the corresponding controller in $stateProvider must be the one where you define gotoBottom().

Here are two working ways of accomplishing your goal:


1. You inject $scope inside the controller ProjectListCtrl. You then define the $scope.gotoBottom function in the same controller.

The scope is the glue between the controller and the view. If you want to call a controller function from your view, you need to define the controller function with $scope

app.controller('ProjectListCtrl', function ($location, $anchorScroll,$scope) {
var selectionList = this;
//selectionList.selections = Selections;
//this.selectedServices = Selections;
$scope.gotoBottom = function() {
  console.log("go to bottom");
  $location.hash('start');
  $anchorScroll();
 };
});

In the list.html view, you can then call the $scope.gotoBottom function just with gotoBottom(): ng-click="gotoBottom()"


2. Or you use the controller as notation, as when you wrote ProjectListCtrl as projectList.

    this.gotoBottomWithoutScope = function(){
      $location.hash('start');
      $anchorScroll();
    };

With this notation, you write this.gotoBottomWithoutScope in the ProjectListCtrl. But in the view, you must refer to it as projectList.gotoBottomWithoutScope().

Please find a working plunker


To learn more about the this and $scope notations, please read this:

Angular: Should I use this or $scope

this: AngularJS: "Controller as" or "$scope"?

and this: Digging into Angular’s “Controller as” syntax

Community
  • 1
  • 1
Manube
  • 5,110
  • 3
  • 35
  • 59
  • Exactly what I was looking for. I really appreciate the extra links and plunker as well. Thank you! – Ken Mar 09 '15 at 17:35