.
203 Ionic Side Menu Record Book Apps From Scratch
Building On Codepen Platform
From a simple Single Page app, we are going to extend it into a Master-Detail app.
User starts by browsing the list on the Master Page.
When the user clicks an item on the list, the app opens the Detail Page.
The selected item on the Master Page is also sent to the Detail Page.
Objective:
1. Grouping data for the same date.
2. Providing Master-Detail pages.
3. Using Ionic Parameter Passing to send data from Master page to Detail page.
Logical Design Approach:
1. Update HTML codes to display Master and Detail Page.
2. Update JS codes to handle Ionic Routing and Control.
3. Update JS codes to handle Parameter Passing.
Data Storage Approach:
Since the data structure may get more complex, we will use a tree analogy to represent the data structure concept in our app.
DataTree = the whole data organization
DataTrunk = the part that holds other data branches
DataBranches = the part that holds specific data groups
The JS codes will be updated with these terminologies.
Continue from the previous tutorial,
1) Prepare Master Page and Detail Page in HTML code
HTML
<html>
<head>
<meta charset="utf-8">
<title>Diary</title>
<meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no, width=device-width">
<!-- Internal Library
<link href="lib/ionic/css/ionic.css" rel="stylesheet">
<script src="lib/ionic/js/ionic.bundle.js"></script>
-->
<!-- Cloud Library -->
<link href="//code.ionicframework.com/nightly/css/ionic.css" rel="stylesheet">
<script src="//code.ionicframework.com/nightly/js/ionic.bundle.js"></script>
<!-- Needed for Cordova/PhoneGap (will be a 404 during development) -->
<script src="cordova.js"></script>
</head>
<body ng-app="app">
<div>
<div>
<ion-nav-bar class="bar-stable">
<ion-nav-back-button></ion-nav-back-button>
</ion-nav-bar>
<ion-nav-view></ion-nav-view>
</div>
</div>
<script id="home.html" type="text/ng-template">
<ion-view title="Home" id="page1">
<ion-nav-buttons side="right" class="has-header">
<button class="button button-icon" ng-click="insertRecord()">
<i class="icon ion-compose"></i>
</button>
</ion-nav-buttons>
<ion-content padding="true" class="has-header">
<h2>MASTER</h2>
<div class = "row">
<div class = "col"><b>Date</b></div>
<div class = "col"><b>Count</b></div>
</div>
<div class = "row" ng-class-odd="'odd'" ng-class-even="'even'" ui-sref="menu.details({param1:978278400000})">
<div class = "col">2001-01-01</div>
<div class = "col">1</div>
</div>
</ion-content>
</ion-view>
</script>
<script id="details.html" type="text/ng-template">
<ion-view title="Details" id="page4">
<ion-nav-buttons side="right" class="has-header">
<button class="button button-icon" ng-click="insertRecord()">
<i class="icon ion-compose"></i>
</button>
</ion-nav-buttons>
<ion-content padding="true" class="has-header">
{{date | date:'yyyy-MM-dd HH:mm:ss Z'}} </ion-content>
</ion-view>
</script>
<script id="cart.html" type="text/ng-template">
<ion-view title="Cart" id="page2">
<ion-content padding="true" class="has-header"></ion-content>
</ion-view>
</script>
<script id="cloud.html" type="text/ng-template">
<ion-view title="Cloud" id="page3">
<ion-content padding="true" class="has-header"></ion-content>
</ion-view>
</script>
<script id="menu.html" type="text/ng-template">
<ion-side-menus enable-menu-with-back-views="false">
<ion-side-menu-content>
<ion-nav-bar class="bar-stable">
<ion-nav-back-button></ion-nav-back-button>
<ion-nav-buttons side="left">
<button class="button button-icon button-clear ion-navicon" menu-toggle="left"></button>
</ion-nav-buttons>
</ion-nav-bar>
<ion-nav-view name="side-menu21"></ion-nav-view>
</ion-side-menu-content>
<ion-side-menu side="left" id="side-menu21">
<ion-header-bar class="bar-stable">
<div class="title">Menu</div>
</ion-header-bar>
<ion-content padding="false" class="side-menu-left has-header ">
<ion-list id="menu-list1">
<ion-item id="menu-list-item1" ui-sref="menu.home" menu-close="">Home</ion-item>
<ion-item id="menu-list-item2" ui-sref="menu.cart" menu-close="">Cart</ion-item>
<ion-item id="menu-list-item3" ui-sref="menu.cloud" menu-close="">Cloud</ion-item>
</ion-list>
</ion-content>
</ion-side-menu>
</ion-side-menus>
</script>
<script id="insertRecord.html" type="text/ng-template">
<div class="modal">
<!-- Modal header bar -->
<ion-header-bar class="bar-secondary">
<h1 class="title">Insert Record</h1>
<button class="button button-clear button-positive" ng-click="closeInsertRecord()">Cancel</button>
</ion-header-bar>
<!-- Modal content area -->
<ion-content>
<form ng-submit="submitInsertRecord(record)">
<div class="list">
<label class="item item-input">
<input type="date" placeholder="Transaction Date" ng-model="record.date">
</label>
<label class="item item-input">
<input type="text" placeholder="Transaction Cost" ng-model="record.cost">
</label>
</div>
<div class="padding">
<button type="submit" class="button button-block button-positive">Insert Record</button>
</div>
</form>
</ion-content>
</div>
</script>
</body>
</html>
|
CSS
.odd {
background-color: WhiteSmoke ;
}
.even {
background-color: Lavender ;
}
|
2) Prepare Master Page and Details Page in JS Code
JS
angular.module('app', ['ionic'])
.factory('DataTree', function() {
return {
all: function() {
var strData = window.localStorage['datatree1'];
if(strData) {
//console.log(strData);
return angular.fromJson(strData);
}
return [];
},
save: function(strData) {
window.localStorage['datatree1'] = angular.toJson(strData);
}
}
})
.controller('homeCtrl', ['$scope', '$stateParams', '$ionicModal', 'DataTree',
function ($scope, $stateParams, $ionicModal, DataTree) {
// Initialize DataTree
var initDataTree = function() {
//initialize with dummy data
var dataTrunk ={};
DataTree.save($scope.dataTrunk);
}
// Get data from storage
// If data length=0, call initDataTree
var dataTrunk=DataTree.all();
if (dataTrunk.length==0){
console.log("Init Data Tree.");
initDataTree();
}
// Else
else{
console.log("Data exists.");
console.log(dataTrunk);
}
// Create and load the Modal
$ionicModal.fromTemplateUrl('insertRecord.html', function(modal) {
$scope.insertRecordModal = modal;
}, {
scope: $scope,
animation: 'slide-in-up'
});
// Called when the form is submitted
$scope.submitInsertRecord = function(record) {
};
// Open our new task modal
$scope.insertRecord = function() {
$scope.insertRecordModal.show();
};
// Close the new task modal
$scope.closeInsertRecord = function() {
$scope.insertRecordModal.hide();
};
}])
.controller('detailsCtrl', ['$scope', '$stateParams',
function ($scope, $stateParams) {
$scope.date=$stateParams.param1;
}])
.controller('cartCtrl', ['$scope', '$stateParams',
function ($scope, $stateParams) {
}])
.controller('cloudCtrl', ['$scope', '$stateParams',
function ($scope, $stateParams) {
}])
.controller('menuCtrl', ['$scope', '$stateParams',
function ($scope, $stateParams) {
}])
.config(function($stateProvider, $urlRouterProvider) {
$stateProvider
.state('menu.home', {
url: '/page1',
views: {
'side-menu21': {
templateUrl: 'home.html',
controller: 'homeCtrl'
}
}
})
.state('menu.details', {
url: '/page4',
params: {
param1: "1"
},
views: {
'side-menu21': {
templateUrl: 'details.html',
controller: 'detailsCtrl'
}
}
})
.state('menu.cart', {
url: '/page2',
views: {
'side-menu21': {
templateUrl: 'cart.html',
controller: 'cartCtrl'
}
}
})
.state('menu.cloud', {
url: '/page3',
views: {
'side-menu21': {
templateUrl: 'cloud.html',
controller: 'cloudCtrl'
}
}
})
.state('menu', {
url: '/side-menu21',
templateUrl: 'menu.html',
controller: 'menuCtrl'
})
$urlRouterProvider.otherwise('/side-menu21/page1')
});
|
3) Outcome.
1) Click the date row.
|
2) The Details page displays the date.
|
No comments:
Post a Comment