Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

UI Router - Remember scroll position when transition between states

I have two views: a start page and a details page.

The start page is long and I want the user to get back to it's last position when it goes back from a details page.

If the user hits the back button it does exactly that but if I link it with ui-sref or an a tag to start it will always go to the top of page.

Is it possible to have the back button functionality in all cases?

<a ui-sref="start">Back</a> - (goes to top)
<a href="javascript:window.history.back()">Back</a> - (wanted behaviour)

I created a quick Plunker to illustrate my example.

http://plnkr.co/edit/z8kdD7ONkL4bML4IaFNz?p=preview

Please click the Launch in a separate window button to get the expected behaviour.

like image 714
Karl Pilsten Avatar asked Nov 01 '22 08:11

Karl Pilsten


1 Answers

Here's what I came up with. When navigating back from the detail view to the list view, pass the ID of the item that was being shown. Then scroll that item in the list back into view.

http://plnkr.co/edit/tWv4UNbBdSbes3XKEcYw?p=preview

html:

<!DOCTYPE html>
<html data-ng-app="myApp">
<head>
    <title>ui router test</title>
    <link rel="stylesheet" href="style.css">
</head>
<body>


<div ui-view  class="main-view"></div>




<script id="templates/start.html" type="text/ng-template">
  <p>Return to {{value}}</p>
  <div class="start">
    <div ng-repeat="i in getNumber(30) track by $index" class="box" id="item_{{$index}}" ui-sref="detail({id:$index})">
       {{$index}}
    </div>
  </div>
</script>
<script id="templates/detail.html" type="text/ng-template">
  <div class="detail">
    Page: {{id}} <br><br>
    <button ui-sref="start({id:id})">Start by sref</button>
    <button ng-click="goBack()">Back by history</button>
    <a href="#/?id={{id}}">Link</a>
  </div>
</script>




<script type="text/javascript" src="http://code.angularjs.org/1.3.14/angular.js"></script>
<script type="text/javascript" src="http://code.angularjs.org/1.2.14/angular-animate.js"></script>
<script type="text/javascript" src="http://code.angularjs.org/1.2.14/angular-touch.js"></script>
<script type="text/javascript" src="https://cdn.cdnhttps.com/cdn-libraries/angular-ui-router/0.2.13/angular-ui-router.min.js"></script>
<script type="text/javascript" src="ui-router-extras.js"></script>

<script type="text/javascript" src="app.js"></script>


</body>
</html>

js:

var app = angular.module('myApp', ['ngAnimate', 'ui.router', 'ct.ui.router.extras.dsr']);

app.config(function ($stateProvider,$urlRouterProvider) {

  $urlRouterProvider.otherwise("/");

  $stateProvider
    .state('start', {
          url: "/?id",
          templateUrl: "templates/start.html",
          controller: 'StartCtrl',
          deepStateRedirect: true
      })
    .state('detail', {
        url: "/detail/:id",
        templateUrl: "templates/detail.html",
        controller: 'DetailCtrl',
        deepStateRedirect: true
    })

});

app.controller('StartCtrl', function($scope, $stateParams, $location, $anchorScroll) {
  $scope.getNumber = function(num) {
      return new Array(num);   
  }
  $scope.value = $stateParams.id;
  if($scope.value) {
    $location.hash("item_" + $scope.value);
    $anchorScroll();
  }
});

app.controller('DetailCtrl', function($scope, $stateParams) {
  $scope.id = $stateParams.id;
  $scope.goBack = function() {
    window.history.back();
  };
});
like image 100
Nicholas Hirras Avatar answered Nov 10 '22 04:11

Nicholas Hirras