Scrolling stops in list when I use $state.go

Hi,

I am new to Ionic so please bear with me.

I have a simple example where I have used the tabs example from the generator.

I have a main view that has a list of students. When I click on one of the students, it goes to the detail view and everything works well. When I click ‘back’ from the detail view, there is no problems with the scrolling of the main list view.

However from the main list view, there is an action where I can create a new student. This takes me to a new screen where I can take a picture, enter the student details and save the student. When I click the ‘save’ button, I display a confirmation dialog and then use the “$state.go()” to return to the main list view.

However, when I do use the “$state.go()” to return to the main list view, the scrolling vertically stops. I can enter individual detail screens by clicking a list item and it will navigate properly to the detail screen however the vertical scrolling on the main screen stops working.

The interesting thing is that the scrolling in the ‘new student’ screen also stops working. (e.g. when I go back to create a new student, the scrolling is not working). When I click in a form field, the keyboard is displayed, then scrolling starts to work again.

It looks like if the scrolling in the ‘New Student’ screen is not working, then the scrolling in the main list is also broken. When I click in the form field to display the keyboard, the scrolling starts to work again. When I navigate back to the main list view, the scrolling works. This sort of makes sense because I assume there is one webview and if the scrolling is not working then it won’t work for any other view that uses it.

I am testing this on the iOS emulator and also on my iPhone 5.

I have listed the main code snippets here and have tried to simplify it as much as possible.

Thanks for your help.

app.js:

// Ionic Starter App

// angular.module is a global place for creating, registering and retrieving Angular modules
// ‘starter’ is the name of this angular module example (also set in a attribute in index.html)
// the 2nd parameter is an array of ‘requires’
// ‘starter.services’ is found in services.js
// ‘starter.controllers’ is found in controllers.js
angular.module(‘starter’, [‘ionic’, ‘starter.controllers’, ‘starter.services’, ‘ngCordova’])

.run(function($ionicPlatform, Friends ) {
$ionicPlatform.ready(function() {
// Hide the accessory bar by default (remove this to show the accessory bar above the keyboard
// for form inputs)
if(window.cordova && window.cordova.plugins.Keyboard) {
cordova.plugins.Keyboard.hideKeyboardAccessoryBar(true);
}
if(window.StatusBar) {
// org.apache.cordova.statusbar required
StatusBar.styleDefault();
}
Friends.openDB();
});
})

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

// Ionic uses AngularUI Router which uses the concept of states
// Learn more here: GitHub - angular-ui/ui-router: The de-facto solution to flexible routing with nested views in AngularJS
// Set up the various states which the app can be in.
// Each state’s controller can be found in controllers.js
$stateProvider

// setup an abstract state for the tabs directive
.state('tab', {
  url: "/tab",
  abstract: true,
  templateUrl: "templates/tabs.html"
})
// Each tab has its own nav history stack:
.state('tab.dash', {
  url: '/dash',
  views: {
    'tab-dash': {
      templateUrl: 'templates/tab-dash.html',
      controller: 'DashCtrl'
    }
  }
})
.state('tab.friends', {
  url: '/friends',
  views: {
    'tab-friends': {
      templateUrl: 'templates/tab-friends.html',
      controller: 'FriendsCtrl'
    }
  }
})
.state('tab.friend-detail', {
  url: '/friend/:friendId',
  views: {
    'tab-friends': {
      templateUrl: 'templates/friend-detail.html',
      controller: 'FriendDetailCtrl'
    }
  }
})
.state('tab.friend-edit', {
  url: '/editfriend/:friendId',
  views: {
    'tab-friends': {
      templateUrl: 'templates/edit-friend-detail.html',
      controller: 'EditFriendDetailCtrl',
    }
  }
})
.state('tab.create-student', {
  url: '/createstudent',
  views: {
    'tab-friends': {
      templateUrl: 'templates/createstudent.html',
      controller: 'CreateStudentCtrl',
    }
  }
})
.state('tab.account', {
  url: '/account',
  views: {
    'tab-account': {
      templateUrl: 'templates/tab-account.html',
      controller: 'AccountCtrl'
    }
  }
});

// if none of the above states are matched, use this as the fallback
$urlRouterProvider.otherwise(‘/tab/dash’);

});

Main List View (tab-friends.html)

<ion-view title="Students">
  <ion-nav-buttons side="right">
  	<button class="button button-clear icon ion-ios7-personadd" ng-click="addNewStudent()">
    </button>
  </ion-nav-buttons>
  <ion-content>
    <ion-list>
      <ion-item ng-repeat="student in students" type="item-text-wrap" href="#/tab/friend/{{student.id}}">
      	<div class="row responsive-sm">
      		<div class="col">
      			<img ng-src="{{student.imageUrl}}" height="250" width="261">	
      		</div>
      		<div class="col">
            <div class="row">
				      {{student.firstName}}  {{student.surname}}    
            </div>
            <div class="row">
              {{student.notes}}
            </div>
            <div class="row">
              {{student.emailList}}
            </div>
      		</div>
   		  </div>     
      </ion-item>
    </ion-list>
  </ion-content>
</ion-view>

Create Student View (createstudent.html)

!--
  This template loads for the 'tab.friend-detail' state (app.js)
  'friend' is a $scope variable created in the FriendsCtrl controller (controllers.js)
  The FriendsCtrl pulls data from the Friends service (service.js)
  The Friends service returns an array of friend data
-->

<ion-view title="Create New Student">
	<ion-nav-buttons side="right">
  		<!-- <button class="button button-clear icon ion-ios7-gear" ng-click=""></button> -->
  		<button class="button button-clear icon ion-ios7-camera" ng-click="takePicture()"></button>
  </ion-nav-buttons>
	<ion-content has-header="true" padding="true">
    <div class="row responsive-sm">
      <div class="col">
        <img ng-src="{{newStudent.imageUrl}}" height="225" width="225">
      </div>
      <div class="col col-67">
        <div class="row">
          <div class="col">
            <label class="item item-input">
              <span class="input-label">First name</span>
              <input type="text" ng-model="newStudent.firstName">
            </label>
          </div>
        </div>
        <div class="row">
          <div class="col">
            <label class="item item-input">
              <span class="input-label">Surname</span>
              <input type="text" ng-model="newStudent.surname">
            </label>
          </div>
        </div>
        <div class="row">
          <div class="col">
            <label class="item item-input">
              <span class="input-label">Notes</span>
              <input type="text" ng-model="newStudent.notes">
            </label>
          </div>
        </div>
        <div class="row">
          <div class="col">
            <label class="item item-input">
              <span class="input-label">Email List</span>
              <input type="text" ng-model="newStudent.emailList">
            </label>
          </div>
        </div>
      </div>
    </div>
    <div class="row responsive-sm">
      <div class="col">
        <div class="row">
          <h4>Monday</h4>
        </div>
        <div class="row">
          9am - 9:30am 
          Activity: Dancing
        </div>
        <div class="row">
          9:30am - 10am
          Activity: Reading
        </div>
      </div>
    </div>
    <div class="row">
      <button class="button button-balanced" ng-click="saveData()">
        Save Changes
      </button>
    </div>
	</ion-content>
</ion-view>

Controllers.js:

angular.module(‘starter.controllers’, [‘ionic’, ‘ui.router’])

.controller(‘DashCtrl’, function($scope) {
})

.controller(‘FriendsCtrl’, function($scope, Friends, $cordovaCamera, $state, $stateParams ) {

$scope.students = Friends.getAllRowsFromDB();

$scope.addNewStudent = function(){
$state.go( ‘tab.create-student’ );
}
})

.controller(‘FriendDetailCtrl’, function($scope, $stateParams, Friends, $cordovaCamera, $state, $ionicNavBarDelegate) {

$scope.takePicture = function(){
var options = {
quality : 100,
destinationType : Camera.DestinationType.DATA_URL,
sourceType : Camera.PictureSourceType.CAMERA,
allowEdit : true,
encodingType: Camera.EncodingType.JPEG,
targetWidth: 100,
targetHeight: 100,
popoverOptions: CameraPopoverOptions,
saveToPhotoAlbum: false
};

  $cordovaCamera.getPicture(options).then(function(imageData) {
    alert( "Picture taken!" );
    $scope.friend.imageData = "data:image/jpeg;base64," + imageData;
  }, function(err) {
     alert( "Oh No! Error occurred." );
  });
  }

Friends.getStudentById($stateParams.friendId)
.then(function( returnedStudent ){
$scope.student = returnedStudent;
console.log( “Read student” );

  	}, function( reason ){
    		console.log( "Error" );
    		$state.go( 'tab.friends' );
    	}, function( update ){
    		console.log( "Update" );
    	}); 
  $scope.editStudent = function( friendId ){
  	$state.go( 'tab.friend-edit', { 'friendId': friendId } );
  }

})

.controller(‘EditFriendDetailCtrl’, function($scope, $stateParams, Friends, $cordovaCamera, $ionicNavBarDelegate) {

Friends.getStudentById($stateParams.friendId)
.then(function( returnedStudent ){
$scope.student = returnedStudent;
console.log( “Read student” );

  	}, function( reason ){
    		console.log( "Error" );
    		$state.go( 'tab.friends' );
    	}, function( update ){
    		console.log( "Update" );
    	}); 

})

.controller(‘AccountCtrl’, function($scope) {
})

.controller(‘NavCtrl’, function($scope, $ionicNavBarDelegate) {
$scope.getPreviousTitle = function() {
return $ionicNavBarDelegate.getPreviousTitle();
};
})

.controller(‘CreateStudentCtrl’, function($scope, $stateParams, Friends, $cordovaCamera, $state, $ionicNavBarDelegate) {

$scope.newStudent = {id: 0, firstName: “”, surname: “”, notes: “”, emailList: “”, imageUrl: “” };
$scope.imageUrl = “”;

$scope.takePicture = function(){

  var options = { 
      quality : 100, 
      destinationType : Camera.DestinationType.FILE_URI, 
      sourceType : Camera.PictureSourceType.CAMERA, 
      allowEdit : true,
      encodingType: Camera.EncodingType.JPEG,
      targetWidth: 100,
      targetHeight: 100,
      popoverOptions: CameraPopoverOptions,
      saveToPhotoAlbum: false
  };
  $cordovaCamera.getPicture(options).then(function( imageUrlFromCamera ) {
    alert( "Picture taken!" );
    $scope.newStudent.imageUrl = imageUrlFromCamera;
  }, function(err) {
     alert( "Oh No! Error occurred." );
  });
  }
  $scope.saveData = function(){
  $state.go( 'tab.friends' );
  }

});

1 Like

I haven’t looked at all of your code, but in my instance it’s because I had the state I wanted, covered up by a modal, then the modal was telling the state to go to the state under the modal. I changed that to just hide the modal and violá