Preserve the scroll location when new items are included in the array within ng-repeat

Is it possible to have a list of messages displayed using ng-repeat and load older messages via ion refresher when the user scrolls to the top? The goal is for the older messages to be added above the current messages while maintaining the scroll position of the current messages.

HTML

<ion-content id="messageScroller" delegate-handle="userMessageScroll">

  <ion-refresher pulling-icon="ion-ios-arrow-thin-down" refreshing-text="loading messages" on-refresh="moreMessages()">
  </ion-refresher>

  <div ng-repeat="message in convo.messages">
    {{message.text}}
  </div>
</ion-content>

JS

$scope.moreMessages = function() {
  $scope.convo.messages = olderMessages().concat($scope.convo.messages)
}

One issue is that when more messages are loaded, the ion-content automatically scrolls to the top, which is not desired.

Is there a way to maintain the scroll position so that loading older messages simply makes them accessible by scrolling up, similar to how it works in iMessage or other chat apps?

Answer №1

Take a look at the $ionicScrollDelegate documentation. It provides functionality to both set and retrieve the scroll position.

Answer №2

In order to achieve the same functionality in my application, I created a directive. Simply place the <load-more-at-top> directive before an <ion-list> within an <ion-content>

For a live example, check out this plunker

myApp.directive('loadMoreAtTop', function($timeout) {
  return {
    restrict: 'E',
    scope: { onScroll: '&onScroll' },
    require: '^$ionicScroll',
    template: function() {
        return '<ion-refresher pulling-text="More..." on-refresh="growBounds()"></ion-refresher>';
    },
    link: function($scope, $element, attrs, scrollCtrl) {
      var scroller = scrollCtrl.$element[0];
      var lastHeight, 
          loading = false;
      $scope.growBounds = function growBounds() {
          loading = true;
          lastHeight = scroller.scrollHeight;
          console.log('lastHeight', lastHeight);
          $scope.onScroll();
      }

      function resetScrollPosition() {
          var height = scroller.scrollHeight;
          var difference = height - lastHeight;
          console.log('difference', difference, 'height', height, 'lastHeight', lastHeight);
          // reset the scroll based on previous height
          scrollCtrl.scrollTo(scrollCtrl.getScrollPosition().left, difference, true);
      }

      function finishGrowBounds() {
        if(loading) {
          $timeout(function() {
              loading = false;
              resetScrollPosition();
              $scope.$broadcast('scroll.refreshComplete');
          }, 0);
        }
      }

      $scope.$parent.$on('scroll.loaded', finishGrowBounds)
    }
  };
});

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Notify of an Invalid CSRF Token within the Action Buttons Present in the Table

I've encountered a problem with the CSRF token when using a Handlebars each loop. I created a data table using the each loop but I'm unable to submit the delete button. The CSRF token only seems to work for submitting new data (POST) and updating ...

Tips for enhancing the fluidity of animations after removing an item from a list

I'm working on a project where I have a list of elements that are removed with an animation when clicked. However, I noticed that when one element is removed, the rest of the elements just jump up instead of smoothly transitioning. Is there a way to m ...

Calculate the sum of hours worked in a day using pure JavaScript, no external libraries required

Hello, I'm new to this website and please excuse me if my English is not perfect, I am trying my best to communicate :) I have been working on a page that calculates the total hours worked in a day and this is what I have achieved so far until 15/06 ...

What is the reason for JavaScript documentation using a nested array to define a function's parameters in its syntax?

I'm struggling to articulate my question, but as I delve into the documentation for JavaScript and Node.js, I notice they define syntax in a way such as this. var new_array = old_array.concat(value1[, value2[, ...[, valueN]]]) It seems like all th ...

What issue is being encountered with this JavaScript generated by PHP?

PHP on the host generates JavaScript code that results in an error stating: missing ; before statement The generated JavaScript code looks like this: try{ obj = document.getElementById('subcat'); }catch(e){} try{ obj.innerHTML = ...

Steps for incorporating events on Jquery UI button

I have a question about utilizing Jquery UI for the first time. After successfully adding a button using Jquery UI, I am now interested in adding events for when a radio switch is turned on and off. When the radiobox is switched on, I want an alert window ...

execute a series of asynchronous functions one after another

async function cancelUserSubscriptionHandler() { const unsubscribe = await fetch("/api/stripe-sessions/cancel-subscription", { method: "PATCH", body: JSON.stringify(), headers: { "Content-Type": "appli ...

Utilizing ngblur and ngfocus to toggle visibility of dropdown options in Angular

Whenever I click off the list without selecting anything, the ngblur event isn't triggered when using select and option. I'm searching for a directive that can help me determine when the options in the select are shown or hidden. Any suggestions ...

Unable to scroll after the webpage redirects

I am currently working on developing a website for uploading images with a comment feature. The comments section is displayed below the image in the 'imagedisplay.php' file. If a user is not logged in, they are redirected to the sign-up page and ...

What is the best way to retrieve data from a database and display it in a select dropdown list

I'm working on creating a Bingo game and I want to include a dropdown list that displays my previous records. How can I retrieve data from a database to populate this select dropdown list? Below is the relevant code snippet in PHP: <html> < ...

Using PHP variables in JavaScript is not compatible

Currently, I am facing an issue where PHP variables inside the javascript code are not being echoed. When I try to echo the variables outside of the javascript, everything works perfectly fine. After carefully reviewing my code multiple times, I still cann ...

What is the solution for resolving an Optional chaining Error in a React project?

Currently, I am delving into the world of react redux while simultaneously constructing an app. One interesting aspect that caught my attention is optional chaining in user authentication. However, this method seems to be throwing an error message. You may ...

Having trouble with the jQuery load function not functioning properly

I have encountered an issue with this code snippet while running it on XAMPP. The alert function is working fine, but the HTML content fails to load. I have included links to jQuery 3.2.1 for reference. index.html $(document).ready(function(){ $("#b ...

Having trouble getting the expected transition effects to work with Vue.js

Currently, I have a display of lists of items through the use of v-for. Initially, only the summary section of each item is visible. Upon clicking on an item, the details section is supposed to appear. This functionality is achieved by adding or removing ...

React Native package identifies a primary module for handling HTTPS requests

For my latest project, I decided to experiment with incorporating HTTPS. I began by creating a new project using expo init test and then installed the HTTPS library with npm install https. Next, I made edits to App.js by adding the following line at the t ...

Deactivate PyV8's automatic garbage collection functionality

I am currently experiencing an issue that appears to be stemming from the interaction between Python and PyV8's garbage collection processes. To temporarily address this problem, I have disabled Python's garbage collection and implemented a worka ...

iPhone - touchstart event not functioning in JavaScript

Looking for a solution to dynamically resize a div in JavaScript when clicking on a link element (<a>). However, the code doesn't seem to function properly on my iPhone. Let's start with a basic link: <a href="#" onfocus="menu()">ME ...

Optimizing Three.js for better performance

Recently, I delved into working with three.js and webgl for a personal project. My goal was to develop a wardrobe model based on user input. You can check out the project at this link: Initially, the rendering speed was fast and smooth without Materials a ...

Arrange and display similar objects together

I have a list of items in a listView that need to be visually grouped based on their class, displayed within boxes. For example, I have 5 items with the following classes: <div class="1"></div> <div class="1"></div> <div class= ...

How can a JQuery slideshow be programmed to only iterate once?

Looking to create a slideshow that transitions between images every two seconds? Check out the code snippet below: HTML: <div class="fadeIn"> <img src="img/city.png" class="remimg" id="city"> <img src="img/shop.png" class="remimg" ...