Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I scroll a div in angularjs

This is easily done with jQuery:

var msgs = $(".messages ul")

var scroll = false

if( msgs[0].scrollHeight  === (msgs.scrollTop() + msgs.outerHeight() ) )
{

    scroll = true

}
$scope.messages.push(data)
if(scroll)
{

    setTimeout(function(){

        msgs.scrollTop(msgs[0].scrollHeight) // Allow it to update!

    },0)


}

To give some context, ul is the container of the messages, I iterate over the array in $scope.messages and if the container is scrolled to the bottom it will stick to the bottom. This implementation works for me.

Now, I recently learned how one shouldn't really use jQuery in angular. But I am wondering, how would I achieve something like this in pure AngularJS?

like image 451
Neikos Avatar asked Sep 14 '13 13:09

Neikos


3 Answers

You can create a directive which will have a variable which when true will go to the top, and will set itself to false once not at top anymore.

How to use:

 <div scroll-to-top="isAtTop">
   <li ng-repeat="stuff in items">{{stuff}}
   <a ng-click="isAtTop = true">Scroll to Top</a>
 </div>

Here's a directive (didn't test, but should work):

angular.module('myApp').directive('scrollToTop', function() {
  return {
    restrict: 'A',
    link: function(scope, elm, attr) {
      var isTop;
      //bind changes from scope to our view: set isTop variable
      //depending on what scope variable is. If scope value
      //changes to true and we aren't at top, go to top
      scope.$watch(attr.scrollToTop, function(newValue) {
        newValue = !!newValue; //to boolean
        if (!isTop && newValue) {
          elm[0].scrollTo(0,0);
        }
        isTop = newValue; 
      });

      //If we are at top and we scroll down, set isTop and 
      //our variable on scope to false.
      elm.bind('scroll', function() {
        if (elm[0].scrollTop !==0 && isTop) {
          //Use $apply to tell angular 
          //'hey, we are gonna change something from outside angular'
          scope.$apply(function() {
            //(we should use $parse service here, but simple for example)
            scope[attr.scrollTop] = false;
            isTop = false;
          });
        }
      });

    }
  };
});
like image 167
Andrew Joslin Avatar answered Sep 30 '22 13:09

Andrew Joslin


I have faced the same issue with table body scrolling. I have resolved it in following way.

Here is my sample html.

<table id="rateplanmapping-scroll">
    <thead>
       <th></th>....
    </thead>
    <tbody >
        <tr ng-repeat="data in datas"> //this is the data
            <td></td>.....
        </tr>
    </tbody>
</table>

Here is the angular code to scroll to the top

angular.element("#rateplanmapping-scroll tbody")[0].scrollTop=0;

I hope it helps. You can put this script in required function, so when particular things happen it get triggered automatically. Or can be attached to event also. I hope it helps.

For div element this can be done in following way

http://plnkr.co/edit/0B4zrFTho6GYuPAS0S1A?p=preview

like image 28
RIYAJ KHAN Avatar answered Sep 30 '22 14:09

RIYAJ KHAN


This is also work $anchorScroll. Example

<div ng-controller="ScrollController">
  <a ng-click="gotoBottom()">Go to bottom</a>
  <a id="bottom"></a> You're at the bottom!
</div>

js:-

.controller(function($scope, $location, $anchorScroll) {
  $scope.gotoBottom = function() {
      // set the location.hash to the id of
      // the element you wish to scroll to.
      $location.hash('bottom');

      // call $anchorScroll()
      $anchorScroll();
    }; 
})
like image 45
vineet Avatar answered Sep 30 '22 14:09

vineet