AngularJs Open Route Page On Modal - angularjs

In my angular-message application I have an option to choose message from template.
I need open the template list as modal.
My problem is that I have a template list as controller + view
How can I open the view without to duplicate my template list code.
$stateProvider
.state('app', {})
.state('app.email', {
}).state('app.email.compose', {
url: '/compose',
data: {
pageTitle: 'Email Compose'
},
templateUrl: 'Assets/app/templates/email_compose.html'
})
.state('app.manage', {
})
.state('app.manage.templates', {
template: '<div ui-view></div>',
url: '/templates',
abstract: true
})
.state('app.manage.templates.list', {
url: '/',
data: {
pageTitle: 'Email List'
},
templateUrl: 'Assets/app/templates/tamplate_list.html'
});
In my app route I want to open the app.manage.template.list
from app.email.compose as modal
How can I do it?

This can easily be done using UI-Bootstrap: https://angular-ui.github.io/bootstrap/ A walkthrough:
Load the Bootstrap CSS asset, note you don't need the JS and jQuery:
<link type="text/css" rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" />
Load the UI-Bootstrap asset:
<script type="application/javascript" src="//cdnjs.cloudflare.com/ajax/libs/angular-ui-bootstrap/1.1.2/ui-bootstrap-tpls.min.js"></script>
Inject the ui.bootstrap module in your application:
angular.module('app', [
'ui.router',
'ui.bootstrap'
]);
Use the onEnter method of your state definition to open a new modal:
.state('myModalState', {
'url': '/myModalUrl',
'onEnter': [
'$uibModal',
function ($uibModal) {
$uibModal.open({
'controller': 'myModalController',
'templateUrl': 'myModalTemplate.html'
}).result.then(
function closed (item) {
// Executed when uibModalInstance is closed, returns value
},
function dismissed () {
// Executed when modal is dismissed/canceled
}
);
}
]
});
Create a controller for your modal and inject $uibModalInstance:
.controller('myModalController', [
'$scope', '$uibModalInstance',
function ($scope, $uibModalInstance) {
$scope.item = 'foobar';
$scope.ok = function () {
$uibModalInstance.close($scope.item);
};
$scope.cancel = function () {
$uibModalInstance.dismiss('cancel');
};
}
]);
And finally a template for the modal:
<div class="modal-header">
<h4 class="modal-title">Title</h4>
</div><!-- /.modal-header -->
<div class="modal-body">
{{item}}
</div><!-- /.modal-body -->
<div class="modal-footer">
<button type="button" class="btn btn-warning" ng-click="cancel()">
Cancel
</button>
<button type="button" class="btn btn-success" ng-click="ok()">
Ok
</button>
</div><!-- /.modal-footer -->
Now everytime you visit /myModalUrl or ui-sref or state.go to myModalState the modal automaticly opens.
Stacksnippet:
angular.module('app', [
'ui.router',
'ui.bootstrap'
]);
angular.module('app').config([
'$stateProvider', '$urlRouterProvider',
function ($stateProvider, $urlRouterProvider) {
$urlRouterProvider.otherwise('/');
$stateProvider.state('root', {
url: '/',
templateUrl: 'root.html',
});
$stateProvider.state('modal', {
url: '/modal',
onEnter: [
'$uibModal', '$state',
function ($uibModal, $state) {
$uibModal.open({
'controller': 'modal',
'templateUrl': 'modal.html',
}).result.then(
function closed (item) {
// Executed when uibModalInstance is closed, returns value
$state.go('root');
},
function dismissed () {
// Executed when modal is dismissed/canceled
$state.go('root');
}
);
}
]
});
}
]);
angular.module('app').controller('modal', [
'$scope', '$uibModalInstance',
function ($scope, $uibModalInstance) {
$scope.item = 'foobar';
$scope.ok = function () {
$uibModalInstance.close($scope.item);
};
$scope.cancel = function () {
$uibModalInstance.dismiss('cancel');
};
}
]);
<!DOCTYPE html>
<html ng-app="app">
<head>
<link type="text/css" rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.6/css/bootstrap.css" />
<script type="application/javascript" src="//cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.8/angular.js"></script>
<script type="application/javascript" src="//cdnjs.cloudflare.com/ajax/libs/angular-ui-router/0.2.15/angular-ui-router.js"></script>
<script type="application/javascript" src="//cdnjs.cloudflare.com/ajax/libs/angular-ui-bootstrap/0.14.3/ui-bootstrap-tpls.js"></script>
<script type="text/ng-template" id="root.html">
<a ui-sref="modal">Open route in modal</a>
</script>
<script type="text/ng-template" id="modal.html">
<div class="modal-header">
<h4 class="modal-title">Title</h4>
</div>
<div class="modal-body">
{{item}}
</div>
<div class="modal-footer">
<button type="button" class="btn btn-warning" ng-click="cancel()">
Cancel
</button>
<button type="button" class="btn btn-success" ng-click="ok()">
Ok
</button>
</div>
</script>
</head>
<body ui-view></body>
</html>
Plunker: http://plnkr.co/edit/5qrD7hB6i8vQEqa8jZ1G?p=preview
UI-Router FAQ on opening a modal when entering a state (mind you it's outdated because of some changes to the UI bootstrap modal directive):
https://github.com/angular-ui/ui-router/wiki/Frequently-Asked-Questions#how-to-open-a-dialogmodal-at-a-certain-state
And here's the reference for UI-Bootstrap's modal directive:
https://angular-ui.github.io/bootstrap/#/modal

I resolve it by adding route as "child" from another state, that refer to same templateUrl templateUrl: 'Assets/app/templates/tamplate_list.html'
$stateProvider
.state('app.email.compose', {
url: '/compose',
data: { pageTitle: 'Email Compose' },
templateUrl: 'Assets/app/templates/email_compose.html'
}).state('app.email.compose.template', {
url: '/template',
data: { pageTitle: 'Email Compose', modal: true },
parent: 'app.email.compose',
templateUrl: 'Assets/app/templates/tamplate_list.html'
}).state('app.manage.templates.list', {
url: '/',
data: { pageTitle: 'Email List' },
templateUrl: 'Assets/app/templates/tamplate_list.html'
});

Related

Not able to inject resolved object from ui-route change into the controller

I am trying to access an http get response called during route change using ui route. The resolve itself happens but i am unable to access the response. I have tried some approaches in "listcontroller" which is shown. I am using a sample httpget url found in the internet for test. Angular version: v1.2.32. ui-route: 1.0.15.
script.js
var app = angular.module("Rasp", ["ui.router"])
.config(['$stateProvider', '$urlRouterProvider',function ($stateProvider, $urlRouterProvider) {
$urlRouterProvider.otherwise("/home");
$stateProvider
.state("ipList", {
url: "/ipList",
templateUrl: "templates/list.html",
controller: "listController",
resolve: {
SensorIP : function($http){
$http.get('https://httpbin.org/ip')
.then(function(response){
console.log('res');
console.log(response);
return response.data.origin;
});
}
}
})
.state("home", {
url: "/home",
templateUrl: "templates/home.html",
controller: "homeController"
});
}])
.controller("RaspController", ['$scope', '$http', function ($scope, $http) {
$scope.getDetails = function () {
// $http.get('https://httpbin.org/ip')
// .then(function (response) {
// console.log(response);
// $scope.response = response;
// },
// function (error) { console.log(error); }
// );
// };
}])
.controller("homeController", ['$scope', function ($scope) {
}])
.controller("listController", ['$scope','SensorIP',function ($scope,SensorIP) {
$scope.sensorList = SensorIP;
var vm = this;
this.list1 = SensorIP;
var logfunc = function() {console.log($scope.sensorlist)};
}])
list.html
<div>
{{list1}}
{{sensorlist}}
<button class="btn btn-danger navbar-btn" ng-click="logfunc()">click</button>
</div>
home.html
<h4>Click on "Get IP List" to get the list of IPs</h4>
<a ui-sref="ipList"><button id="button" >Get IP List</button></a>
index.html
<!DOCTYPE html>
<head>
<title>Title(To be changed)</title>
<!--JS-->
<script type="text/javascript" src="../node_modules/angular/angular.js"></script>
<script type="text/javascript" src="../node_modules/#uirouter/angularjs/release/angular-ui-router.js"></script>
<script type="text/javascript" src="script.js"></script>
<!-- -->
<!--CSS-->
<link rel="stylesheet" href="../css/style.css">
<!-- -->
</head>
<body>
<div ng-app="Rasp">
<div ng-controller="RaspController">
<div class="sidenav">
<!--
<a ui-sref="home" id="dot-button"><button class="btn btn-danger navbar-btn" >Home</button></a>
<a ui-sref="ipList" id="dot-button"><button class="btn btn-danger navbar-btn" >IP List</button></a>
-->
<a ui-sref="home">home</a>
<a ui-sref="ipList" >ipList</a>
</div>
<div>
<ui-view id="uiview"></ui-view>
</div>
</div>
</div>
</body>

How do I display the inner html of directive inside a dialog?

What do I want to do?
I want to have a directive with some html inside. The directive renders a button and when the button is clicked I open a modal dialog. I want to display the html declared inside the directive in the dialog. Different spots where I use the directive might have different html messages in the modal dialog.
Here is the code that I've got.
app.js:
var app = angular.module('plunker', ['ngResource', 'ui.bootstrap', 'ui.bootstrap.modal']);
app.controller('MainCtrl', function($scope) {
$scope.name = 'World';
})
.controller('dialogController', ['$scope', '$modalInstance', 'params', function ($scope, $modalInstance, params) {
$scope.info = params.info;
$scope.close = function () {
$modalInstance.dismiss('cancel');
};
}])
.directive('someDirective', ['$modal', '$timeout', function ($modal, $timeout) {
return {
scope: {
title: '#title'
},
restrict: 'AE',
replace: true,
templateUrl: 'someDirective.html',
transclude: true,
link: function ($scope, $element, attr, controller, transclude) {
//transclude(function(clone, scope) {
// debugger;
// });
$scope.info = "test"; // I would like to set this to the value within the inner html of the directive.
$scope.openDialog = function () {
var modalInstance = $modal.open({
templateUrl: 'dialog.html',
controller: 'dialogController',
backdrop: 'static',
windowClass: 'ie-app-modal-window-narrow',
resolve: {
params: function () {
return {
info: 'SomeHtml' //<-- here I want to it to the html from inside someDirective
};
}
}
});
modalInstance.result.then(function () {
},
function () { });
};
}
};
}])
;
dialog.html:
<!DOCTYPE html>
<html>
<head>
<title>Add attachment</title>
<meta charset="utf-8"/>
</head>
<body>
<div class="modal-header">
<button type="button" class="close"><span aria-hidden="true" ng-click="close()">×</span></button>
<strong>Add Attachment</strong>
</div>
<div class="modal-body">
<!-- Text input-->
<div class="alert alert-info" role="alert">
{{info}}
</div>
</div>
<div class="modal-footer">
<div class="form-group">
<div style="float: left">
<button class="btn btn-default" ng-click="close()" ng-disabled="isDisabled">Close</button>
</div>
</div>
</div>
</body>
</html>
index.html:
<!DOCTYPE html>
<html ng-app="plunker">
<head>
<meta charset="utf-8" />
<title>AngularJS Plunker</title>
<script data-require="jquery#2.2.4" data-semver="2.2.4" src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script>
<link data-require="bootstrap#3.3.7" data-semver="3.3.7" rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" />
<script data-require="bootstrap#3.3.7" data-semver="3.3.7" src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<script>document.write('<base href="' + document.location + '" />');</script>
<link rel="stylesheet" href="style.css" />
<script data-require="angular.js#1.2.x" src="https://code.angularjs.org/1.2.28/angular.js" data-semver="1.2.28"></script>
<script data-require="angular-ui#0.4.0" data-semver="0.4.0" src="http://rawgithub.com/angular-ui/angular-ui/master/build/angular-ui.js"></script>
<script data-require="angular-ui-bootstrap#1.3.3" data-semver="0.12.0" src="http://angular-ui.github.io/bootstrap/ui-bootstrap-tpls-0.12.0.min.js"></script>
<script data-require="angular-resource#1.2.28" data-semver="1.2.28" src="https://code.angularjs.org/1.2.28/angular-resource.js"></script>
<script src="app.js"></script>
</head>
<body ng-controller="MainCtrl">
<p>Hello {{name}}!</p>
<some-directive title="Hello">
<b>Testing</b>
</some-directive>
</body>
</html>
someDirective.html:
<div class="panel panel-default" >
<div class="panel-heading">
{{title}}
</div>
<div class="panel-body" ng-style="loadingStyle">
<button class="btn btn-sm btn-default" ng-click="openDialog();" type="button">Open</button>
</div>
</div>
I found this: How to get inner html of custom directive? but I don't know exactly how it would work in my case. I am not using the compile method.
Plnker
Thanks
To Pass value from someDirective to dialog.
First inject $rootScope into someDirective like so:
directive('someDirective', ['$modal', '$timeout', '$rootScope', function ($modal, $timeout, $rootScope) {
Now we create a new scope and add a value to it (in this case, $scope.info), and pass it into the modalScope. angular will then pass this along to the modal's controller as the $scope variable.
$scope.info = "test";
$scope.openDialog = function () {
var modalScope = $rootScope.$new();
modalScope.info = $scope.info;
var modalInstance = $modal.open({
scope: modalScope,
templateUrl: 'dialog.html',
controller: 'dialogController',
backdrop: 'static',
windowClass: 'ie-app-modal-window-narrow',
});
modalInstance.result.then(function () {
},
function (result) {
});
};
So inside the modal's controller we have access to variable we just passed in!
.controller('dialogController', ['$scope', '$modalInstance', function ($scope, $modalInstance) {
console.log($scope.info); //prints "test"
$scope.close = function () {
$modalInstance.dismiss('cancel');
};
}])
Now the opposite. To pass from modal back to someDirective:
There's several ways but in my opinion the best way is to use the promises. modalInstance.result returns a promise. This promise is resolved if the modal is closes and rejected if the modal is dismissed. Whether resolved or rejected, a value/object can be passed along as a parameter.
Example, opening the dialog as before:
$scope.info = "test";
$scope.openDialog = function () {
var modalScope = $rootScope.$new();
modalScope.info = $scope.info;
var modalInstance = $modal.open({
scope: modalScope,
templateUrl: 'dialog.html',
controller: 'dialogController',
backdrop: 'static',
windowClass: 'ie-app-modal-window-narrow',
});
modalInstance.result.then(function (returnStuff) {
//This is called when the modal is closed.
//returnStuff is whatever you want to return from the dialog when it's closed
},
function (returnStuff) {
//This is called when the modal is dismissed.
//returnStuff is whatever you want to return from the dialog when it's dismissed
});
};
And to actually close/cancel the dialog:(from inside the dialog)
//pass any value you want back
$modalInstance.close({foo:"Ayyylmao", bar:42});
$modalInstance.dismiss('dismissed');
If I understood it correctly, this is what you want, http://plnkr.co/edit/tOe8tZ5VWfOCkocQaEKo?p=preview
$scope.info = $element.get(0).innerHTML.trim();
Based on this posting, I managed to find something that works for the specific angularjs versions that I am using. I made another plnkr.
The relevant changes are:
dialog.html: I used <div ng-bind-html="info"></div>
<!DOCTYPE html>
<html>
<head>
<title>Add attachment</title>
<meta charset="utf-8"/>
</head>
<body>
<div class="modal-header">
<button type="button" class="close"><span aria-hidden="true" ng-click="close()">×</span></button>
<strong>Add Attachment</strong>
</div>
<div class="modal-body">
<!-- Text input-->
<div class="alert alert-info" role="alert">
<div ng-bind-html="info"></div>
</div>
</div>
<div class="modal-footer">
<div class="form-group">
<div style="float: left">
<button class="btn btn-default" ng-click="close()" ng-disabled="isDisabled">Close</button>
</div>
</div>
</div>
</body>
</html>
app.js - I added the controller property in the someDirective directive and the code grabs the html and sets the info property.
var app = angular.module('plunker', ['ngResource', 'ui.bootstrap', 'ui.bootstrap.modal']);
app.controller('MainCtrl', function($scope) {
$scope.name = 'World';
})
.controller('dialogController', ['$scope', '$modalInstance', 'params', function($scope, $modalInstance, params) {
$scope.info = params.info;
$scope.close = function() {
$modalInstance.dismiss('cancel');
};
}])
.directive('someDirective', ['$modal', '$timeout', '$sce', function($modal, $timeout, $sce) {
return {
scope: {
title: '#title',
html: '#'
},
restrict: 'AE',
replace: true,
templateUrl: 'someDirective.html',
transclude: true,
controller: function($scope, $element, $attrs, $transclude) {
$transclude(function(clone,scope){
$scope.info = angular.element('<div>').append(clone).html().trim();
});
},
link: {
pre: function (scope, iElement, iAttrs, controller) {
//debugger;
},
post: function($scope, $element, attr, controller) {
//transclude(function(clone, scope) {
// debugger;
// });
//debugger;
//$scope.info = "test"; // I would like to set this to the value within the inner html of the directive.
//debugger;
$scope.openDialog = function() {
var modalInstance = $modal.open({
templateUrl: 'dialog.html',
controller: 'dialogController',
backdrop: 'static',
windowClass: 'ie-app-modal-window-narrow',
resolve: {
params: function() {
return {
info: $sce.trustAsHtml($scope.info) //<-- here I want to set it to the html from inside someDirective
};
}
}
});
modalInstance.result.then(function() {},
function() {});
};
}
}
};
}])
;

Make two layouts share the same $scope

I want to propose two layouts (ie, horizontal and vertical) for my contents. So switching in the selector will lead automatically to the corresponding layout. Here is the JSBin:
<html ng-app="flapperNews">
<head>
<script src="https://code.jquery.com/jquery.min.js"></script>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" rel="stylesheet" type="text/css" />
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.7/angular.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-router/0.3.2/angular-ui-router.js"></script>
<script type="text/ng-template" id="horizontal.tpl">
<textarea ng-model="one"></textarea>, <textarea ng-model="two"></textarea>
<br><br>{{one}}+{{two}}
</script>
<script type="text/ng-template" id="vertical.tpl">
<textarea ng-model="one"></textarea><br><textarea ng-model="two"></textarea>
<br><br>{{one}}+{{two}}
</script>
<script>
var app = angular.module('flapperNews', ['ui.router']);
app.config(['$stateProvider', function ($stateProvider) {
$stateProvider
.state('entry', {
url: '/',
params: { tpl: 'vertical' },
templateUrl: function (params) {
return params.tpl + ".tpl"
}
})
}]);
app.controller('MainCtrl', ['$scope', '$state', function ($scope, $state) {
$scope.one = "one";
$scope.two = "two";
$scope.layouts = ["horizontal", "vertical"];
$scope.$watch('layout', function () {
$state.go('entry', {tpl: $scope.layout});
})
}])
</script>
</head>
<body ng-controller="MainCtrl">
<select ng-model="layout" ng-init="layout = 'horizontal' || layouts[0].value" ng-options="x for x in layouts"></select>
<br><br>
<ui-view></ui-view>
</body>
</html>
However, with the above code, each time we change the view, $scope.one and $scope.two are reset to their initial values. I would hope the change in their textarea would remain regardless of the change of layout.
Does anyone know how to solve this?
Easy sharing same data between different views by using factories (AngularJS factory documentation). Try this example, it uses a simple factory named myFactory to share data between controllers. This also does work on the same controller as in your case.
var myApp = angular.module("myApp",[ "ui.router"]);
myApp.config(function ($stateProvider, $urlRouterProvider){
$stateProvider.state("state1", {
url: "#",
template: '<p>{{ aValue }}</p><button ng-click="bindValue(\'its me\')">Bind value</button>',
controller: "myController"
}).state("state2", {
url: "#",
template: '<p>{{ aValue }}</p><button ng-click="bindValue(\'its me\')">Bind value</button>',
controller: "myController"
});
});
myApp.controller( "myController", function($scope, myFactory) {
$scope.aValue = myFactory.myValue;
$scope.bindValue = function (value) {
$scope.aValue = value;
myFactory.myValue = value;
}
});
myApp.factory('myFactory', function () {
return {
myValue: ''
}
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.13/angular.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/angular-ui-router/0.2.8/angular-ui-router.min.js"></script>
<div ng-app="myApp">
<nav>
<a ui-sref="state1">State 1</a>
<a ui-sref="state2">State 2</a>
</nav>
<div ui-view></div>
</div>
I think that you should use nested views - you can define main controller on parent route state and define two nested states corresponding to two views. This way parent controller will remain (it's not re-initialised when child states are switched) and only nested states views will be changed. Something like this:
$stateProvider
.state('myState', {
url: '/test/',
template: '<div ui-view></div>',
controller: function() {
//main controller shared by child states
...
}
})
.state('myState.view1', {
url: '/test/view1'
templateUrl: 'tpl-1.hmtl',
...
})
.state('myState.view2', {
url: '/test/view2'
templateUrl: 'tpl-2.hmtl',
...
})

Angular UI bootstrap modal is not working

I am new to angular and bootstrap. This is my Plunk.
This is my code of DemoController:
angular.module('app', ['ui.bootstrap'])
.controller('demoController', function($modal) {
this.message = 'It works!';
key = 1000;
this.modalInstance = this.modal = function(){
$modal.open({
controllerAs: 'modalController as modal',
templateUrl: 'modal.html',
resolve: {
key: function() {
return key;
}
}
});
};
this.modalInstance.result.then(function (optionSelected){
if(optionSelected == 'yes')
{
}
});
});
ModalController:
angular.module('app')
.controller('modalController', function($scope, $modalInstance, key) {
$scope.featureName = key;
$scope.yes = function () {
$modalInstance.close('yes');
};
$scope.discard = function () {
$modalInstance.close('discard');
};
$scope.goback = function () {
$modalInstance.close('goback');
};
});
Modal.html:
<script type="text/ng-template" id="modal.html">
<div class="modal-content">
<div class="modal-body">
<p>Do you want to save the changes to {{featureName}} </p>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" ng-click="yes()">Yes</button>
<button type="button" class="btn btn-default" ng-click="discard()">Discrad</button>
<button type="button" class="btn btn-default" ng-click="goback()">Go Back</button>
</div>
</div>
</script>
Index.html:
<!DOCTYPE html>
<html>
<head>
<link data-require="bootstrap-css#3.1.1" data-semver="3.1.1" rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css" />
<script data-require="angular.js#1.2.16" data-semver="1.2.16" src="https://code.angularjs.org/1.2.16/angular.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/angular-ui-bootstrap/0.11.0/ui-bootstrap-tpls.js"></script>
<script src="script.js"></script>
</head>
<body ng-app="app" ng-controller="demoController as demo">
<h1>{{ demo.message }}</h1>
<button class="btn btn-primary" ng-click="demo.modal()">Open modal</button>
</body>
</html>
I want to pass data from demo controller to modal controller. I want to have separate html and controller for the modal dialog. Somehow this is not working.
Here's a working plunker based on your own plunk: http://plnkr.co/edit/VDDyDuBoZ30tAk2kQKoc?p=preview
List of changed things:
In index.html, I added Ctrl.js to the list of loaded scripts.
In modal.html, removed the script tags surrounding the html. When loading the modal html from an external file, the script tags aren't necessary.
Finally in script.js made a few changes, ending up with the following:
angular.module('app', ['ui.bootstrap'])
.controller('demoController', function($modal) {
this.message = 'It works!';
var key = 1000;
this.modal = function() {
var modalInstance = $modal.open({
controller: 'modalController',
templateUrl: 'modal.html',
resolve: {
key: function() {
return key;
}
}
});
modalInstance.result.then(function(optionSelected) {
if (optionSelected === 'yes') {
console.log("Yes selected!")
}
})
}
});
Basically, this.modal is the function that's executed when clicking on the Open modal button. In the function, we initialize a variable modalInstance, which is the $modal.open function call. We also handle the modal result inside the this.modal function, not outside of it.
You have a lot of mistakes there. Here is your example:
plnkr.co/edit/47WJrWHW7ueYXBpiYJbA?p=preview

Nested views error - only after refreshing page

I am a total beginner with Angluar.JS. I want to have a Single Page Application with a row of tabs, each of which can contain another row of tabs, each of which contains a view.
So, I asked this question and accepted an answer, which had a demo at http://plnkr.co/edit/BUbCR8?p=preview.
The demo was very close, but used a list instead of the second row of tabs, so I am trying to modify the code. So far, I just have a skeleton, a proof of concept of nested tabs with views. I will drop the real contents in later.
I will post my code below, but here is the problem:
when I drag & drop the index,html file into the browser, it works fine. I can click around and what I expect to happen seems to happen. There is not much to see when moving between the tabs Left, Centre & Right; so far the action is on Link & Link2 of the Left tab.
Seems perfect - until press F5 and refresh the page, then I start geeing errors in the JS Console:
Error: Could not resolve '.link2' from state 'left.link1'
at Object.t.transitionTo (http://angular-ui.github.io/ui-router/release/angular-ui-router.min.js:7:8834)
at Object.t.go (http://angular-ui.github.io/ui-router/release/angular-ui-router.min.js:7:8182)
at http://angular-ui.github.io/ui-router/release/angular-ui-router.min.js:7:15639
at http://code.angularjs.org/1.2.9/angular.js:13585:28
at completeOutstandingRequest (http://code.angularjs.org/1.2.9/angular.js:4111:10)
at http://code.angularjs.org/1.2.9/angular.js:4418:7
If I drag the file back onto the browser, all is fine again. Same behavior in Chrome & FireFox.
Any idea what I am doing wrong?
Index.html
<!DOCTYPE html>
<html ng-app="plunker">
<!-- http://plnkr.co/edit/BUbCR8?p=preview -->
<head>
<meta charset="utf-8" />
<title>Nested tabs demo</title>
<link data-require="bootstrap-css#*" data-semver="3.0.3" rel="stylesheet" href="http://netdna.bootstrapcdn.com/bootstrap/3.0.3/css/bootstrap.min.css" />
<link data-require="font-awesome#*" data-semver="4.0.3" rel="stylesheet" href="http://netdna.bootstrapcdn.com/font-awesome/4.0.3/css/font-awesome.css" />
<script>
document.write('<base href="' + document.location + '" />');
</script>
<script data-require="angular.js#1.2.x" src="http://code.angularjs.org/1.2.9/angular.js" data-semver="1.2.9"></script>
<script data-require="ui-bootstrap#*" data-semver="0.10.0" src="http://angular-ui.github.io/bootstrap/ui-bootstrap-tpls-0.10.0.min.js"></script>
<script data-require="angular-animate#*" data-semver="1.2.9" src="http://code.angularjs.org/1.2.9/angular-animate.js"></script>
<script src="http://angular-ui.github.io/ui-router/release/angular-ui-router.min.js"></script>
<!-- Our stuff -->
<script src="app.js"></script>
<script src="controller.js"></script>
</head>
<body ng-controller="Tabs">
<div style="border-style:solid;border-width:1"> <!-- FixMe: uses CSS, not inline style -->
<h3>Nested tabs demo</h3>
</div>
<!-- ToDO: how to set initial state & view
<span>$state = <b>{{$state.current.name}}</b></span><br>
<span>$state url = <b>{{$state.$current.url.source}}</b></span>
-->
<tabset>
<tab>
<tab-heading>
<a ui-sref="left" ui-sref-active="active">Left</a>
</tab-heading>
</tab>
<tab>
<tab-heading>
<a ui-sref="centre" ui-sref-active="active">Centre</a>
</tab-heading>
</tab>
<tab>
<tab-heading>
<a ui-sref="right" ui-sref-active="active">Right</a>
</tab-heading>
</tab>
</tabset>
<div class="row">
<br>
<div ui-view="viewA">
<!--Here is the A content-->
</div>
</div>
</body>
app.js
var app = angular.module('plunker', ['ui.bootstrap', 'ui.bootstrap.tpls', 'ui.router'])
.run(['$rootScope', '$state', '$stateParams',
function ($rootScope, $state, $stateParams) {
// It's very handy to add references to $state and $stateParams to the $rootScope
// so that you can access them from any scope within your applications.For example,
// <li ng-class="{ active: $state.includes('contacts.list') }"> will set the <li>
// to active whenever 'contacts.list' or one of its decendents is active.
$rootScope.$state = $state;
$rootScope.$stateParams = $stateParams;
}]);
app.config(function($stateProvider,$locationProvider, $urlRouterProvider) {
$urlRouterProvider.otherwise("/");
$locationProvider.html5Mode(false).hashPrefix('!');
$stateProvider
.state('left', {
url: "/",
views: {
"viewA": {
template: '<h1>Left Tab, index.viewA</h1><br></h1><div>' +
'<tabset>' +
' <tab>' +
' <tab-heading>' +
' <a ui-sref=".link1">Link1</a><br>' +
' </tab-heading>' +
' </tab>' +
' <tab>' +
' <tab-heading>' +
' <a ui-sref=".link2">Link2</a></div>' +
' </tab-heading>' +
' </tab>' +
'</tabset>' +
'<div class="col-xs-6">' +
'<div ui-view="viewA.link1"></div>' +
'<div ui-view="viewA.link2"></div></div>'
},
"viewC": {
template: 'Left Tab, viewC <div ui-view="viewC.link1"></div>' +
'<div ui-view="viewC.link2"></div>'
}
}
})
.state('left.link1', {
url: 'link1',
views: {
"viewA.link1": {
template: '<h2>viewA Nest Link1</h2><ul>' +
'<li ng-repeat="thing in link1things">{{thing}}</li></ul>',
controller: 'Tab1Link1Ctrl',
data: {}
},
"viewC.link1": {
template: 'Link1'
}
}
})
.state('left.link2', {
url: 'link2',
views: {
"viewA.link2": {
template: '<h2>viewA Nest Link2</h2><ul>' +
'<li ng-repeat="thing in link2things">{{thing}}</li></ul>',
controller: 'Tab1Link2Ctrl',
data: {}
},
"viewC.link2": {
template: 'Link2'
}
}
})
.state('centre', {
url: "/centre",
views: {
"viewA": {
template: '<h1>Centre Tab, viewA</h1>',
controller: '2ndTabCtrl',
data: {}
},
"viewC": {
template: 'Centre Tab, viewC <div ui-view="viewC.list"></div>'
}
}
})
.state('right', {
url: "/right",
views: {
"viewA": {
template: '<h1>Right Tab, viewA</h1>',
controller: '2ndTabCtrl',
data: {}
},
"viewC": {
template: 'Right Tab, viewC <div ui-view="viewC.list"></div>'
}
}
});
});
controller.js
app.controller('Tabs', ['$scope', '$stateParams', '$state',
function($scope, $stateParams, $state) {}
]);
app.controller('2ndTabCtrl', ['$scope', '$stateParams', '$state',
function($scope, $stateParams, $state) {}
]);
app.controller('Tab1Link1Ctrl', ['$scope', '$stateParams', '$state',
function($scope, $stateParams, $state) {
$scope.link1things = ["A", "Set", "Of", "Things", "link1", "viewA"];
}
]);
app.controller('Tab1Link2Ctrl', ['$scope', '$stateParams', '$state',
function($scope, $stateParams, $state) {
$scope.link2things = ["A", "Set", "Of", "Things", "link2", "viewA"];
}
]);
in your template youre triggering state '.link1':
<a ui-sref=".link1">Link1</a>
but you havent defined a state called '.link1' in your state config. You do have a state named 'left.link1'. Is that what you meant?
P.S. In the future just create a plunkr with your examples, its a pain scrolling through multiple files here

Resources