kamilkp / angular-vs-repeat

Virtual Scroll for AngularJS ngRepeat directive
http://kamilkp.github.io/angular-vs-repeat/
MIT License
818 stars 228 forks source link

Is there a way to force scroll to an item #144

Open mdarveau opened 8 years ago

mdarveau commented 8 years ago

Hi,

First of all, thank you for this lib. Great work!

Is there a way to scroll to an element on load? I have a bunch of records in a table and I would like to scroll down to a specific entry once the table is displayed.

Thank you

mdarveau commented 7 years ago

I created this directive (coffeescript):

angular.module( 'maligue.common' ).directive "vsRepeatScrollTo", [ '$parse', ( $parse ) ->
  {
    restrict: 'A'
    link: ( scope, elem, attrs ) ->
      getOffset = $parse( attrs.vsRepeatScrollTo )

      if attrs.vsHorizontal?
        scrollSizeAttr = 'scrollWidth'
        scrollPositionFunction = 'scrollLeft'
      else
        scrollSizeAttr = 'scrollHeight'
        scrollPositionFunction = 'scrollTop'

      scrollToWatch = scope.$watch( ->
        offset = getOffset( scope )
        scrollSize = elem[0][scrollSizeAttr]
        return unless offset?
        if elem[scrollPositionFunction]() != offset && scrollSize > offset
          elem[scrollPositionFunction]( offset )
          if Math.floor( elem[scrollPositionFunction]() ) == Math.floor( offset )
            scrollToWatch()
      )

  }
]

And then use it on the same element as vs-repeat: vs-repeat-scroll-to="getInitialPosition()" where getInitialPosition should return the x or y position that should be set initially.

amosuro commented 7 years ago

I think the best thing you can do is create a directive that sets the scrollTop property to the target element's index (found on the model) and multiply that by the height of the target element (assuming all elements have the same height).

E.g

function scrollToIndex() {
        const index = 4; // this is the index of the item you  want to scroll to
        const rowHeight = 30; // each row in my table have a height of 30px
        const offset = rowHeight * index; // set scrollTop offset to 30 x 4 = 120

        scrollContainer.scrollTop = offset; // this will scroll your vs-repeat table to the correct pixel offset
};