Ionic how to go back inside a nested view - html

I can't see to get go back transition to work.
I have this abstract view called main that holds this child views.
<div class="bar bar-header bar-stable">
<button class="button button-clear button-positive">Log out</button>
</div>
<div class="clearfix"></div>
<ion-side-menus>
<!-- Center content -->
<ion-side-menu-content style="padding-top: 45px">
<ion-nav-view name="categories"></ion-nav-view>
<ion-nav-view name="products"></ion-nav-view>
<ion-nav-view name="payments"></ion-nav-view>
</ion-side-menu-content>
<!-- Left menu -->
<ion-side-menu expose-aside-when="large" style="padding-top: 45px">
<ion-view>
<ion-content>
<ul class="list has-header" id="itemLists">
</ul>
</ion-content>
</ion-view>
<div class="bar bar-subfooter auto-height" style="padding:0">
<ul class="list">
<li class="item">Total <span class="pull-right" id="total"></span></li>
</ul>
</div>
<div class="bar bar-footer">
<div class="text-center">
<div class="bar bar-footer bar-positive">
<div class="title">Pay</div>
</div>
</div>
</div>
</ion-side-menu>
</ion-side-menus>
This is my app.js that holds all routes.
angular.module('starter', ['ionic', 'starter.controllers', 'starter.services', 'ngStorage'])
.run(function($ionicPlatform) {
$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) {
StatusBar.styleDefault();
}
});
})
.config(function($stateProvider, $urlRouterProvider, $ionicConfigProvider){
$ionicConfigProvider.views.transition('none');
$urlRouterProvider.otherwise('/');
$stateProvider
.state('login',{
url: '/',
templateUrl: 'templates/login.html',
controller: 'loginController'
})
.state('main', {
url: '/main',
templateUrl: 'templates/main.html',
controller: 'mainController',
abstract: true
})
.state('main.categories', {
url: '/categories',
views: {
'categories': {
templateUrl: 'templates/categories.html',
controller: 'categoriesController'
}
}
})
.state('main.products', {
url: '/products/:productId',
views: {
'products': {
templateUrl: 'templates/products.html',
controller: 'productsController'
}
}
})
.state('main.payments', {
url: '/payments',
views: {
'payments': {
templateUrl: 'templates/payments.html',
controller: 'paymentsController'
}
}
})
})
I have this state main.products which a child of the main abstract view.
When I click the pay button on the left-down corner, it takes me to the main.payments view.
This is the code for the main.payments view
<ion-view view-title='Payments'>
<ion-content>
<div class="row">
<div class="col col-25">
Cash
</div>
<div class="col col-25">
Credit Card
</div>
<div class="col col-25">
Discount
</div>
<div class="col col-25">
<button ng-click="cancel()" class="button button-large button-block button-assertive">Cancel</button>
</div>
</div>
<div class="row">
<div class="col col-25">
<button ng-click="goBack()" class="button button-large button-block button-royal">Go Back</button>
</div>
</div>
</ion-content>
Now when I press the go back button the URL in the page changes to the previous page but the view doesn't transition there, until I refresh the page.
This is my payment controller that handles the go back button transition.
.controller('paymentsController', function($scope, $localStorage, $log, $state, $window, $ionicHistory){
$scope.cancel = function(){
$localStorage.total= '';
$state.go('main.categories');
$window.location.reload();
};
$scope.goBack = function(){
$ionicHistory.goBack();
}
})

Main.payments and main.products are adjacent views not child view, although main.payments.view is child of main.payments and main.payments is child of main
So you can't travel to adjacent state.
if you want to traverse you have to specifically mention the $state.go(STATE_NAME); or you can use ui-sref in button itself
Note: add "cache:false" to abstract view

Related

Adding Modal dialog to the Header file in MVC project does not work

I implemented a modal popup as a part of the header.cshtml file in MVC project. the issue is that it does not show the dialog box (not working)
The only way I was able to make work is when I put the both the button and the modal container in the header file.
The modal body is a long text and it should not be a part of the header file.
I tried several tutorials, read modal documentation, and applied fixes from stackoverflow nothing worked for me.
I must be missing something very simple and trivial I just can't see it.
Below is the code in the Roles.cshtml file where the modal container is created and the text is written
#{
Layout = "~/Views/Shared/SubLayout.cshtml";
}
#{
ViewBag.Title = "Roles";
}
<div class="container">
<div class="styleguide-spacer-modals"></div>
</div>
<div class="modal" id="modal-active" aria-hidden="true">
<div class="modal__overlay bg-modal" tabindex="-1"
data-micromodal-close>
<div class="modal__container" role="dialog" aria-modal="true"
aria-labelledby="modal-title-1">
<header class="modal__header">
<h1 class="modal__title h2" id="modal-title-1">
<h2>Roles</h2>
<br />
</h1>
</header>
<main class="modal__content">
BLABLA......
</main>
<footer class="modal__footer">
<button class="button button-primary"
aria-label="submit">
close
</button><button class="button button-secondary" data-
micromodal-close
aria-label="closing">
close
</button>
</footer>
</div>
</div>
</div>
Then the Header.cshtml file look like this: where I added "btnTrigger" and AJAX script to call and show the modal
#model TR.Service.Web.ViewModels
<header class="header" role="banner">
<!--1A: Portal header -->
<div class="portal-header">
<div class="container portal-header-inner">
<button class="button button-tertiary button-menu-open js-menu-
open ml-auto" aria-haspopup="menu" title="mobil menu">Menu</button>
<a href="#" class="button button-secondary" role="button">
login
</a>
</div>
<button class="button button-primary" id="btnTrigger"
data-micromodal-trigger="modal-passive">
Read me
</button>
<div id="divContainer"></div>
</div>
<div class="solution-header">
blabla........
</div>
</header>
#section scripts
{
<script>
$(function () {
$('#btnTrigger').unbind();
$('#btnTrigger').on('click', function () {
$.ajax({
url: '#Url.Action("Betingelser", "Rolles")',
type: 'POST',
data: { },
success: function (arr) {
$('#divContainer').html(arr); //Load your HTML to DivContainer
$('#exampleModal').modal('show'); //Once loaded, show the modal
},
error: function (err) {
console.log(err);
}
});
});
});
</script>
}
Then in my Home controller I have the actionResult that should return the
partial view
public ActionResult Roles()
{
return PartialView("Roles");
}
I can't see why this is not working. Please help.
Pupop should appear when click on the button with id =btnTrigger
Here is a working code
First since the Header.cshtml is part of the SubLayout.cshtml, move the #section scripts to the Roles.cshtml like below, you cna also put it in your Layout but without the #section scripts tag. I did'nt use the modal you had in your question. But this is a working modal
#{
Layout = "~/Views/Shared/SubLayout.cshtml";
}
#{
ViewBag.Title = "Roles";
}
<div class="container">
<div class="styleguide-spacer-modals"></div>
</div>
<div id="exampleModal" class="modal fade" role="dialog">
<div class="modal-dialog">
<!-- Modal content-->
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal">×</button>
<h4 class="modal-title">Roles</h4>
</div>
<div class="modal-body">
<p>Content</p>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
#section scripts
{
<script>
$(function () {
$('#btnTrigger').unbind();
$('#btnTrigger').on('click', function () {
$.ajax({
url: '#Url.Action("Betingelser", "Rolles")',
type: 'POST',
data: { },
success: function (arr) {
$('#divContainer').html(arr); //Load your HTML to DivContainer
$('#exampleModal').modal('show'); //Once loaded, show the modal
},
error: function (err) {
console.log(err);
}
});
});
});
</script>
}
Then your Header.cshtml now looks like this
<header class="header" role="banner">
<!--1A: Portal header -->
<div class="portal-header">
<div class="container portal-header-inner">
<button class="button button-tertiary button-menu-open js-menu-
open ml-auto" aria-haspopup="menu" title="mobil menu">
Menu
</button>
<a href="#" class="button button-secondary" role="button">
login
</a>
</div>
<button class="button button-primary" id="btnTrigger"
data-micromodal-trigger="modal-passive">
Read me
</button>
<div id="divContainer"></div>
</div>
<div class="solution-header">
</div>
</header>
Also change the Home controller method to
public ActionResult Roles()
{
return View();
}

router stopped working after an update

I used to have the attached code working just fine, but then an update caused it to stop working. I was not able to make the adjustments so hopefully someone here has gone through it. The last block after the HTML is just smarty code to include the js file. The URL I am getting is: mySite.com/policies#!/#refund
which does not load anything. If I manually delete the second # to make it /policies#!/refund it does work.
This is the js file:
var app = angular.module('myApp', ['ngRoute', 'ui.bootstrap', 'dialogs.main',
'summernote', 'angular-loading-bar', 'ngAnimate', 'fiestah.money', 'ui.ace',
'ui.select', 'ngCart']);
app.config(function ($routeProvider, $locationProvider) {
$routeProvider
.when('/', {
templateUrl: '/templates/main-app/policy/policy-reviews.tpl',
controller: 'mainCtrl'
})
.when('/reviews', {
templateUrl: '/templates/main-app/policy/policy-reviews.tpl',
controller: 'mainCtrl'
})
.when('/currency', {
templateUrl: '/templates/main-app/policy/policy-currency.tpl',
controller: 'mainCtrl'
})
.when('/refund', {
templateUrl: '/templates/main-app/policy/policy-refund.tpl',
controller: 'mainCtrl'
});
});
app.controller('mainCtrl', function ($scope, $rootScope, $filter, $http, $location, dialogs) {
console.log("in ctrl");
});
This is the template:
<div ng-controller="mainCtrl">
<div class="act-dash">
<nav class="navbar-default content-header blue" role="navigation" style="position:relative;">
<!-- We use the fluid option here to avoid overriding the fixed width of a normal container within the narrow content columns. -->
<div id="admin-collapse" class="pad-left-fix" style="bottom:0px;">
<div class="container"><h1>Terms and Policies</h1></div>
<ul class="nav navbar-nav" style="position:relative; bottom:0px">
<li><span class="glyphicon glyphicon-eye-open"> </span>Comments and Reviews</li>
<li><span class="glyphicon glyphicon-usd"> </span>Currency Conversion</li>
<li><span class="glyphicon glyphicon-usd"> </span>Refund Policy</li>
</ul>
</div>
<!-- /.navbar-collapse -->
</nav>
<div class="content narrow-content margin-fix">
<div class="row margin-fix margin-bottom-fix div-table" style="width:100%;">
<div class="col-md-12 pad-left-fix pad-right-fix div-table-cell">
<div style="text-align: left;">
<div id="main">
<!-- angular templating -->
<!-- this is where content will be injected -->
<div ng-view>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
{assign var="extra_js" scope="global" value="
<script type=\"text/javascript\" src=\"/js/angular-apps/policy.js\">
</script>
"}
You can Add Following line of code in your app.config, Just below
$routeProvider and see if it will work. Before run Please clear cache
and coockies on your browser.
$locationProvider.hashPrefix('');

Ionic ng-click navigate to state removes menu on left

I have the following menu template
The below <ion-side-menus> lives in template/menu/menu.html
<ion-side-menus>
<ion-side-menu-content>
<ion-nav-bar class="bar-stable nav-title-slide-ios7">
<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="menuContent" animation="slide-left-right"></ion-nav-view>
</ion-side-menu-content>
<ion-side-menu enable-menu-with-back-views="true" side="left">
<ion-header-bar class="bar-assertive">
<h1 class="title">Menu</h1>
</ion-header-bar>
<ion-content>
<div ui-view="leftMenuContent"></div>
</ion-content>
</ion-side-menu>
</ion-side-menus>
When navigating from a html file using the following technique
<ion-view view-title="Nutrition">
<ion-content class="padding">
<button class="button button-full button-calm" ng-click="viewPlans()">Plans
</button>
</ion-content>
</ion-view>
home.controller('NutritionController', function ($state) {
$scope.viewPlans = function () {
$state.go('app.home.nutrition.plan');
};
});
The <ion-side-menus> gets completely removed and replaced with the content that was loaded from the state i.e just one screen without menus on the left.
Navigating from a html file using the following technique
<ion-view view-title="Nutrition">
<ion-content class="padding">
<a ui-sref="app.home.nutrition.plan" class="button button-full button-calm" menu-close>Plans</a>
</ion-content>
</ion-view>
The menu on the left stays there only closes and the content gets loaded into the content part of the menu.
Below is my routes:
.state('app', {
url: '',
abstract: true,
templateUrl: 'template/menu/menu.html',
controller: 'MainCtrl as mainCtrl'
})
.state('app.home', {
url: '/home',
views: {
'menuContent#app': {
templateUrl: 'template/home.html',
controller: "HomeController as homeCtrl"
},
'leftMenuContent#app': {
templateUrl: 'template/menu/left/main.html',
controller: "HomeController as homeCtrl"
}
}
})
.state('app.home.nutrition', {
url: '/nutrition',
views: {
'menuContent#app': {
templateUrl: 'template/nutrition.html',
controller: "NutritionController as nutritionCtrl"
},
'leftMenuContent#app': {
templateUrl: 'template/menu/left/nutritionMenu.html'
}
}
})
.state('app.home.nutrition.plan', {
url: '/plan',
views: {
'menuContent#app': {
templateUrl: 'template/plan/plan.html',
controller: "PlanController as planCtrl"
},
'leftMenuContent#app': {
templateUrl: 'template/menu/left/planMenu.html'
}
}
});
Is there a way that I can keep the menu on the left when doing a ng-click?

How to parse and use a json object passed from parent page

I apologize in advance if this has already been answered. I've Googled around for a few hours now, and I still haven't found anything that seems to answer my exact question.
Here is my code:
<ion-content>
<div class="list">
<div style="padding: 0px; margin: 0px;" class="item">
<div class="row"
ng-repeat="x in orders|orderBy:'order_id'| filter:{ paid: '0' } ">
<div class="col left">
{{x.order_id}}
</div> <div class="col left">
<a ng-href="#/tab/orderdetails?detail={{x.detail}}">订单详情</a>
</div>
</div>
</div>
</div>
</ion-content>
x.detail is the json object i want to pass to the newly opened page "orderdetails.html":
<script id="templates/orderdetails.html" type="text/ng-template">
<ion-view view-title="OrderDetails">
<ion-content class="padding">
<p>Here I want to display order details...</p>
var obj = this.href.split('?')[1];
console.log(obj);
<p>
<a class="button icon ion-home" href="#/tab/home"> Home</a>
</p>
</ion-content>
</ion-view>
</script>
app.js:
.state('tabs.orderdetails', {
url: "/orderdetails",
views: {
'home-tab': {
templateUrl: "templates/orderdetails.html"
}
}
})
I want to know how to parse and use the passed object in "orderdetails.html". Thanks.
You can add controllers to the views,
then declare a $scope.json_name = json value
to be able to use the variable the you angular template
<script id="templates/orderdetails.html" type="text/ng-template">
<ion-view view-title="OrderDetails">
<ion-content class="padding">
<p>Here I want to display order details...</p>
this is a variable name: {{ name }}
<p>
<a class="button icon ion-home" href="#/tab/home"> Home</a>
</p>
</ion-content>
</ion-view>
</script>
then you can add the controller like this
.state('tabs.orderdetails', {
url: "/orderdetails",
views: {
'home-tab': {
templateUrl: "templates/orderdetails.html",
controller: function ($scope) {
$scope.name = "this is a variable name";
}
}
}
})
you can refer to angular documentation

AngularJS - Custom directives - one gives error "Template must have exactly one root element" while other works

here is my index.html
<html ng-app="dempApp">
<head>
<!-- CSS -->
</head>
<body>
<div ng-switch on="templateHeader">
<div ng-switch-when="login">
<div loginheader></div>
</div>
<div ng-switch-when="home">
<div homeheader></div>
</div>
</div>
</body>
<!-- JS scripts -->
</html>
My app.js has the directives
demoClientApp.directive('loginheader', function () {
return {
restrict: 'A',
replace: true,
templateUrl:'views/loginheader.html'
}
})
demoClientApp.directive('homeheader', function () {
return {
restrict: 'A',
replace: true,
templateUrl:'views/homeheader.html'
}
})
loginheader.html is like following
<div class="main-container">
<div class="main-content">
<div class="row">
<div class="col-sm-10 col-sm-offset-1">
<div class="login-container">
<div class="center">
<h1>
<span class="blue">DemoApplication</span>
</h1>
</div>
<div class="position-relative">
<div ng-view></div>
</div><!-- /position-relative -->
</div>
</div><!-- /.col -->
</div><!-- /.row -->
</div>
</div><!-- /.main-container -->
It has ng-view inside and similarly for homeheader directive I have another html file which also has ng-view.
Based on path, I am setting value of templateHeader and its switching the directive. But the page is blank now and shows error.
Error: Template must have exactly one root element. was: <div class="main-container">
<div class="main-container">
<div class="main-content">
<div class="row">
<div class="col-sm-10 col-sm-offset-1">
<div class="login-container">
<div class="center">
<h1>
<span class="blue">DemoApplication</span>
</h1>
</div>
<div class="position-relative">
<div ng-view></div>
</div><!-- /position-relative -->
</div>
</div><!-- /.col -->
</div><!-- /.row -->
</div>
</div><!-- /.main-container -->
If I don't use the loginheader directive and use the html directly, it is working fine and the other homeheader directive is working. Why is that?
How to solve it?
UPDATE 1
It is working. But the problem is when the path is just localhost:9000 it is not redirecting to login. Earlier it used to route to login if the user enters a wrong path or not logged in. So now when I just type the url localhost:9000, it is showing the blank page and the error. Here is how I route.
var demoClientApp=angular.module('demoClientApp', ['ngCookies']);
demoClientApp.config(['$routeProvider', '$locationProvider',
function($routeProvider,$locationProvider) {
$routeProvider
.when('/login', {
templateUrl: 'login.html',
controller: 'LoginController'
})
.when('/register', {
templateUrl: 'register.html',
controller: 'RegisterController'
})
.when('/home', {
templateUrl: 'views/dashboard.html',
controller: 'DashboardCtrl'
})
.otherwise({
redirectTo: '/login'
});
}]);