Trying to get a side menu working with ion-nav-view


#1

I have a HTML page as follows:

<body ng-app="merchant" ng-controller="AppCtrl">
	<ion-side-menus>
		<ion-side-menu-content drag-content="true">
			<ion-nav-bar type="bar-positive" back-button-type="button-icon" back-button-icon="ion-ios7-arrow-back" animation="nav-title-slide-ios7"></ion-nav-bar>
			<ion-nav-buttons side="left"></ion-nav-buttons>
			<ion-nav-view class="slide-left-right"></ion>
		</ion-side-menu-content>
		<ion-side-menu side="left" is-enabled="true">
			<ion-list>
				<div ng-repeat="group in groups">
					<ion-item class="item-stable"
						ng-click="toggleGroup(group)"
						ng-class="{active: isGroupShown(group)}">
						<i class="icon {{group.iconClass}}"></i>
						{{group.name}}
					</ion-item>
					<ion-item class="item-accordion"
						ng-click="route($event, item.state)"
						ng-repeat="item in group.items"
						ng-show="isGroupShown(group)">
						{{item.title}}
					</ion-item>
				</div>
			</ion-list>
		</ion-side-menu>
	</ion-side-menus>
</body>

I am trying to to simply toggle the left side menu but cannot seem to get it working for me. When I click the menu button I get a JS error logged in the console:

TypeError: Cannot read property ‘sideMenuController’ of undefined

I am very new to ionic and angular but this has tripped me up. Am not sure what I am trying to achieve is best practice in the way that side menus and navigations are nested etc

This is my main controller:

/**
 * Application level controller
 * @param  {Object} $rootScope [Root scope]
 * @param  {Object} $scope     [Controller scope]
 * @param  {Object} $q         [Deferred]
 * @param  {Object} $state
 * @return {Object}
 */
merchant.controller('AppCtrl', function($rootScope, $scope, $q, $state, $ionicSideMenuDelegate) {

	/**
	 * The menu list grouped items
	 * @type {Array}
	 */
	$scope.groups = [{
		name: 'Payment transaction',
		iconClass: 'ion-information-circled',
		isActive: false,
		items: [{
			title: 'Transaction history enquiry',
			state: 'historyEnquiry',
			isActive: false
		}, {
			title: 'Daily transaction report',
			state: 'dailyReport',
			isActive: false
		}]
	}, {
		name: 'Bill arrangements',
		iconClass: 'ion-folder',
		isActive: false,
		items: [{
			title: 'Update monthly bill amount',
			state: 'monthly',
			isActive: false
		}, {
			title: 'Upload eStatement',
			state: 'upload',
			isActive: false
		}]
	}, {
		name: 'Report',
		iconClass: 'ion-document-text',
		isActive: false,
		items: [{
			title: 'Outstanding report',
			state: 'report',
			isActive: false
		}, {
			title: 'Settlement status',
			state: 'status',
			isActive: false
		}, {
			title: 'Customer eStatements',
			state: 'eStatements',
			isActive: false
		}]
	}, {
		name: 'My preferences',
		iconClass: 'ion-gear-a',
		isActive: false,
		items: [{
			title: 'Update merchant details',
			state: 'details',
			isActive: false
		}, {
			title: 'Comission setting',
			state: 'setting',
			isActive: false
		}]
	}];

	$scope.toggleLeft = function onToggleLeft() {
		$ionicSideMenuDelegate.toggleLeft();
	};

	/**
	 * [leftButtons description]
	 * @type {Array}
	 */
	$scope.leftButtons = [{
		type: 'button-icon icon ion-navicon',
		tap: function(e) {
			$scope.toggleLeft();
		}
	}];

	/**
	 * Roytes the application state on click of menu item
	 * @param  {Object} event
	 * @param  {String} route
	 * @return {Function}
	 */
	$scope.route = function(event, route) {
		event.preventDefault();
		return $state.go(route);
	};

	/**
	 * If the given group is the selected group, deselect it
	 * else, select the given group
	 * @param  {Object} group
	 * @return {Object}
	 */
	$scope.toggleGroup = function(group) {
		if ($scope.isGroupShown(group)) {
			return $scope.shownGroup = null;
		} else {
			return $scope.shownGroup = group;
		}
	};

	/**
	 * Sets the $scope variable to true of false
	 * @param  {Object}
	 * @return {Boolean}
	 */
	$scope.isGroupShown = function(group) {
		return $scope.shownGroup === group;
	};

	return this;

});

Then the client login html which is the default route:

<ion-view title="'Merchant login'" left-buttons="leftButtons">
	<ion-content has-header="true" padding="true" scroll="false" has-bouncing="false" ng-controller="LoginCtrl">
		<div class="list list-inset">
			<label class="item item-input">
				<input type="text" id="username" name="username" placeholder="Username" ng-model="username" />
			</label>
			<label class="item item-input">
				<input type="password" id="password" name="password" placeholder="Password" ng-model="password" />
			</label>
		</div>
		<div>
			<button ng-click="login($event)" class="button button-block button-positive">Sign in</button>
		</div>
	</ion-content>
</ion-view>

Want to show and hide sub (side)menu items
#2

it’s pretty tough to look at raw code without context. If you setup a CodePen sample, it might be easier to see what’s going on.

However, I’ll try. Where are you trying to close the side-menu? I don’t see that?

In you menu items, you can add menu-close attribute to them. When clicked, they will automatically close the menu.

<ion-item nav-clear menu-close href="#/app/search">
    Search
</ion-item>

#3

Thanks, I will take a look.

I think I am going to try to be less complex and just have a login template without menu and when someone is authenticated they are navigated to a proper ion-nav-view and side menu set up more alike the examples.


#4

I set up an example here:

I am not sure how or where to set the MainCtrl to enable the menu?


#5

I solved this with the latest beta :smile: