Pedro Justo
Pedro Justo

Reputation: 4289

Vertical and horizontal scrollable ion-content with ion-infinite-scroll only vertically

Inside my ion-content I have a list which when scrolled to the bottom more items are loaded (provided by ion-infinite-scroll which calls 'LoadMore()'). The problem is that if I set direction = xy to ion-content, ion-infinite-scroll calls 'LoadMore()' if I scroll vertically and horizontally.

It is possible to my ion-infinite-scroll only call 'LoadMore()' when scrolled vertically?

Upvotes: 0

Views: 3282

Answers (1)

Pedro Justo
Pedro Justo

Reputation: 4289

Currently ionic version beta.13 does not support this feature. I already have posted my suggested solution on ionic repository ( https://github.com/driftyco/ionic/issues/1073 )

I've created 'ion-infinite-scroll-fixed' directive wich differs only in last if block:

.directive('ionInfiniteScrollFixed', ['$timeout', function($timeout) {
  function calculateMaxValue(distance, maximum, isPercent) {
    return isPercent ?
      maximum * (1 - parseFloat(distance,10) / 100) :
      maximum - parseFloat(distance, 10);
  }
  return {
    restrict: 'E',
    require: ['^$ionicScroll', 'ionInfiniteScrollFixed'],
    template: '<i class="icon {{icon()}} icon-refreshing"></i>',
    scope: true,
    controller: ['$scope', '$attrs', function($scope, $attrs) {
      this.isLoading = false;
      this.scrollView = null; //given by link function
      this.getMaxScroll = function() {
        var distance = ($attrs.distance || '2.5%').trim();
        var isPercent = distance.indexOf('%') !== -1;
        var maxValues = this.scrollView.getScrollMax();
        return {
          left: this.scrollView.options.scrollingX ?
            calculateMaxValue(distance, maxValues.left, isPercent) :
            -1,
          top: this.scrollView.options.scrollingY ?
            calculateMaxValue(distance, maxValues.top, isPercent) :
            -1
        };
      };
    }],
    link: function($scope, $element, $attrs, ctrls) {
      var scrollCtrl = ctrls[0];
      var infiniteScrollCtrl = ctrls[1];
      var scrollView = infiniteScrollCtrl.scrollView = scrollCtrl.scrollView;

      $scope.icon = function() {
        return angular.isDefined($attrs.icon) ? $attrs.icon : 'ion-loading-d';
      };

      var onInfinite = function() {
        $element[0].classList.add('active');
        infiniteScrollCtrl.isLoading = true;
        $scope.$parent && $scope.$parent.$apply($attrs.onInfinite || '');
      };

      var finishInfiniteScroll = function() {
        $element[0].classList.remove('active');
        $timeout(function() {
          scrollView.resize();
          checkBounds();
        }, 0, false);
        infiniteScrollCtrl.isLoading = false;
      };

      $scope.$on('scroll.infiniteScrollComplete', function() {
        finishInfiniteScroll();
      });

      $scope.$on('$destroy', function() {
        void 0;
        if(scrollCtrl && scrollCtrl.$element)scrollCtrl.$element.off('scroll', checkBounds);
      });

      var checkBounds = ionic.animationFrameThrottle(checkInfiniteBounds);

      //Check bounds on start, after scrollView is fully rendered
      setTimeout(checkBounds);
      scrollCtrl.$element.on('scroll', checkBounds);

      function checkInfiniteBounds() {
        if (infiniteScrollCtrl.isLoading) return;

        var scrollValues = scrollView.getValues();
        var maxScroll = infiniteScrollCtrl.getMaxScroll();

        if ((maxScroll.left !== -1 && scrollValues.left >= maxScroll.left && $attrs.notOnHorizontal !=="true") ||
            (maxScroll.top !== -1 && scrollValues.top >= maxScroll.top && $attrs.notOnVertical !=="true")) {
          onInfinite();
        }
      }
    }
  };
}]);

and in my HTML:

 <ion-infinite-scroll-fixed 
          not-on-horizontal="true"
          ng-if="infiniteScroll.canLoad"
          on-infinite="infiniteScroll.loadMore();"
          distance="1%">
 </ion-infinite-scroll-fixed>

I hope this can help somebody :)

Upvotes: 1

Related Questions