I'm using angular bootstrap modal.
termsText is populated and the scope.productTerms does contain a value. But for some reason when I output {{ productTerms }} inside the modal the value is not being displayed. Why?
js
$scope.openProductTerms = function (termsText) {
$scope.productTerms = termsText <-- has a value in console.log()
var modalInstance = $modal.open({
templateUrl: 'myModalTerms.html',
controller: ModalInstanceCtrl
});
var ModalInstanceCtrl = function ($scope, $modalInstance) {
$scope.ok = function () {
$modalInstance.dismiss('OK');
};
};
html
{{ productTerms }} < ==== value shows outside modal
<script type="text/ng-template" id="myModalTerms.html">
<div class="modal-body">
{{ productTerms }} <==== same value does not show insdie modal?
</div>
<div class="modal-footer">
<button class="btn btn-primary" ng-click="ok()">OK</button>
</div>
</script>
The modal has a new controller and therefore a new scope.
services.js
angular.module('services',[]).
factory('sharedService', function($rootScope) {
var sharedService = {};
sharedService.value = null;
sharedService.prepForBroadcast = function(value) {
this.value = value;
this.broadcastItem();
};
sharedService.broadcastItem = function() {
$rootScope.$broadcast('shared');
};
return sharedService;
});
controller.js
$scope.openProductTerms = function (termsText) {
sharedService.prepForBroadcast(termsText);
var modalInstance = $modal.open({
templateUrl: 'myModalTerms.html',
controller: ModalInstanceCtrl
});
lastController.js
var ModalInstanceCtrl = function ($scope, $modalInstance,sharedService) {
$scope.$on('shared', function() {
$scope.productTerms = sharedService.value;
});
$scope.ok = function () {
$modalInstance.dismiss('OK');
};
};
Try using {{$parent.productTerms}} within your HTML
From my experience, it seems that the angular bootstrap modal creates a new scope. So by referencing $parent first, you'll be able to get your model's value.
Related
I am working on angular application where I am displaying pop up message using bootstrap modal.
but its not displaying dynamic header text and body text.Pop up is showing but with blank header and body.
my main controller is as below
var requestUserController = function ($scope, $window, $uibModal, DataService) {
$scope.modalOptions = {
headerText: "",
bodyText: ""
}
var onServerError = function (data) {
$scope.modalOptions.headerText = "Error";
$scope.modalOptions.bodyText = data.statusText;
var serverModel = $uibModal.open({
templateUrl: window.serverUrl + 'app/ErrorMessages/PopUpErrorMessage.html',
controller: 'requestUserController',
scope: $scope
});
$scope.cancelForm = function () {
serverModel.close();
};
};
var onClientDataComplete = function (data) {
//window.hideProgress();
$scope.requestUser.clientDrp = data;
$scope.clientSelected = $scope.requestUser.clientDrp[0];
};
//window.showProgress();
DataService.getListofClients()
.then(onClientDataComplete, onServerError);
}
App.controller("requestUserController", ["$scope", "$window", "$uibModal", "DataService", requestUserController]);
and html for modal is
<div class="modal-header" ng-class="{true: 'alert-success', false: 'alert-danger'}[modalOptions.headerText == 'Success']">
<h3>{{modalOptions.headerText}}</h3>
</div>
<div class="modal-body">
<p>{{modalOptions.bodyText}}</p>
</div>
<div class="modal-footer">
<input type="button" class="btn icn-ok" value="Ok"
ng-click="cancelForm()" />
</div>
But pop up is showing blank header and body text
Remove loading of 'requestUserController' from your code and use the following code for open popup window
var serverModel = $uibModal.open({
templateUrl: window.serverUrl + 'app/ErrorMessages/PopUpErrorMessage.html',
scope: $scope
});
I want to generate a modal pop up on click of a button. I am using ui bootstrap of angular with $modal service.
Now, when I click on button, I am writing the following code.
$scope.modalOpen = function () {
var modalInstance = $modal.open({
templateUrl: 'views/includes/someModal.html',
controller : //here I want to use the same controller where the current function is getting called
});
};
I am unable to call the same controller. Am I making any mistake? I tried Google but no success :( Please suggest. Thanks in advance :)
I am assuming the whole reason you want to do this is so you can share data (state) between the modal and the current controller.
You can achieve this without having to share the controller, using the resolve field on the modal configuration.
function CurrentController($scope, $modal) {
$scope.list = [];
$scope.modalOpen = function () {
var modalInstance = $modal.open({
templateUrl: 'views/includes/someModal.html',
controller : 'SomeOtherController',
resolve: {
list: function() { return $scope.list; }
}
});
};
}
This means that list will be dependency injected into SomeOtherController.
function SomeOtherController($scope, list) {
$scope.list = list;
}
resolve (Type: Object) - Members that will be resolved and passed
to the controller as locals; it is equivalent of the resolve
property in the router.
See the docs for $modal in angular-ui bootstrap.
If you open your modal from your controller, you can attempt something like this :
var myCtrl = this;
$scope.modalOpen = function () {
var modalInstance = $modal.open({
templateUrl: 'views/includes/someModal.html',
controller : myCtrl
});
};
But I don't think it's a good practice to reuse a controller instance.
You probably don't want to make it use the same controller. Since the scope isn't isolated, your modal can call functions from your current controller. You can also have an inline controller like the following:
The reason why you couldn't use functions from your current scope is you would have to give the modal your current scope to do that. Be careful when you do this. Your modal can mess up your current object. I went ahead and created a "save" and "cancel" button so that you can undo the changes.
Html
<div ng-controller="simpleController">
{{ item.title }}
<button ng-click="open();">Click Me</button>
</div>
modal template
<script type="text/ng-template" id="views/includes/someModal.html">
<div class="modal-header">
<h3 class="modal-title">Title!</h3>
</div>
<div class="modal-body">
title: {{ item.title }}<br/>
Click the buttons below to change the title throught the controller's function
<button ng-click="fn('test');">test</button>
<button ng-click="fn('test 1');">test 1</button>
<button ng-click="fn('test 2');">test 2</button>
</div>
<div class="modal-footer">
<button ng-click="close(true);">Save</button>
<button ng-click="close();">Close</button>
</div>
</script>
javascript
angular.module("myApp", ['ui.bootstrap']).controller("simpleController", ["$scope", "$uibModal", function($scope, $uibModal){
$scope.item = { title: "test", stuff: "other stuff"};
$scope.fn = function(title){
$scope.item.title = title;
};
$scope.open = function () {
var intialItem = angular.copy($scope.item);
var modalInstance = $uibModal.open({
templateUrl: 'views/includes/someModal.html',
controller: ["$scope", function(scope){//add other functionality here
scope.close = function(save){
if(!save){
$scope.item = intialItem;
}
modalInstance.close();
}
}],
scope: $scope
}).result.then(function(){
}, function(){
$scope.item = intialItem;//modal was dismissed
});
};
}]);
Noob alert!
The question here is exactly the one that I have: angularjs - Accessing ui-bootstrap modal dismiss and close function from another controller
However, I don't understand the answer that was chosen as correct! I understand the words but don't understand how to share the controller.
I have an app controller that opens a modal, and within the modal's template, I have a directive. I would like to be able manipulate the modal instance from within the directive's controller.
Here's my markup:
<script type="text/ng-template" id="settingsModal">
<div class="modal-header">
<h3 class="modal-title">Confirm update!</h3>
</div>
<div class="modal-body">
<calendar-settings cid="calendarId"/>
</div>
<div class="modal-footer">
<!-- I want these buttons inside the directive instead -->
<button class="btn btn-primary" ng-click="ok()">OK</button>
<button class="btn btn-warning" ng-click="cancel()">Cancel</button>
</div>
</script>
In the body of the modal, I am calling the calendarSettings directive, and I'd like to be able to use the .dismiss and .close methods of the modal instance from within my directive.
Here's what the open method looks like:
var modalInstance = $modal.open({
templateUrl: 'settingsModal',
controller: 'ModalInstanceController',
resolve: {
item: function() {
return $scope.sEntry;
},
cid: function() {
return id;
}
},
reject: {
item: function() {
return $scope.sEntry;
},
cid: function() { return null; }
}
});
And here's the ModalInstanceController:
calendarsApp.controller('ModalInstanceController', function($scope, $modalInstance, item, cid){
$scope.item = item;
$scope.calendarId = cid;
console.log(item);
$scope.ok = function () {
$modalInstance.close($scope.item);
};
$scope.cancel = function () {
$modalInstance.dismiss('cancel');
};
});
I think what I want to do is easy, but I'm not sure how to expose the modal instance controller to the directive, or if there is a different approach I should be thinking about.
NOTE: I didn't paste the code from the directive in here. But I'm trying to access the close and dismiss methods of the modal instance from within my directive's controller.
Thanks for any help!
So
var modalInstance = $modal.open({
templateUrl: 'settingsModal',
controller: 'ModalInstanceController',
resolve: {
item: function() {
return $scope.sEntry;
},
cid: function() {
return id;
}
},
reject: {
item: function() {
return $scope.sEntry;
},
cid: function() { return null; }
}
//This comes from ModalInstanceController result is
//equivalent to whatever u send back
}).result.then(function(result){
console.log(result); //Press f12 on chrome and go to console.
});
calendarsApp.controller('ModalInstanceController', function($scope, $modalInstance, item, cid){
$scope.item = item;
$scope.calendarId = cid;
console.log(item);
$scope.ok = function () {
//You are sending back $scope.item but if you want everything
//send back the $scope which is equivalent to sending back //ModalInstanceController
// $modalInstance.close($scope.item);
$modalInstance.close($scope);
};
$scope.cancel = function () {
$modalInstance.dismiss('cancel');
};
});
In this plunk I have the following:
A control object shared between the controller and the directive.
The directive declares a method in the control object.
The controller invokes the method to set a value.
The directive is included in an Angular UI Modal.
For some reason the control object is empty when the modal is opened (look at the console log). How to invoke the method from the controller to set the field value?
HTML
<div ng-app="app" ng-controller="myCtl">
<button ng-click="openModal()">Open modal</button>
<script type="text/ng-template" id="myModalContent.html">
<div class="modal-header">
<h4 class="modal-title">The Title</h4>
</div>
<ddl control="ddlControl"></ddl>
<div class="modal-footer">
<button type="submit">Submit</button>
</div>
</script>
</div>
Javascript
var app = angular.module('app', ['ui.bootstrap']);
app.controller('myCtl', function($scope,$uibModal) {
$scope.ddlControl = {};
$scope.openModal = function() {
$scope.modalInstance = $uibModal.open({
templateUrl: 'myModalContent.html',
scope: $scope
});
console.log($scope.ddlControl);
$scope.ddlControl.set();
};
})
.directive('ddl', function () {
var directive = {};
directive.restrict = 'EA';
directive.scope = {
control: '='
};
directive.template = '<div>someValue: {{someValue}}</div>';
directive.link = function (scope, element, attrs) {
scope.control = scope.control || {};
scope.control.set = function() {
scope.someValue = 1;
};
};
return directive;
});
There is a race condition between opening the modal and running a digest of the modal HTML.
When the button is clicked $scope.openModal() is executed. The modal opens and gets into the digest phase. But javascript is not waiting until the digesting has been completed, so it continues executing $scope.openModal() until the end.
You need to handle the promise of $uibModal.open().rendered(). The uibModal resolves the rendered promise when it's done.
$scope.openModal = function() {
$scope.modalInstance = $uibModal.open({
templateUrl: 'myModalContent.html',
scope: $scope
}).rendered.then(function() {
console.log($scope.ddlControl);
$scope.ddlControl.set();
});
};
The $uibModal.open() function returns the following:
Object {result: Promise, opened: Promise, rendered: Promise}
In the promise block of rendered, you can safely make use of the fields that has been changed by the directive.
Plunker: http://plnkr.co/edit/GnIThstxkuR06felh8Pe?p=preview
I have a problem pushing items inside the array of a modal. I'm getting undefine value.
I followed all the examples that i can find but it is not working when it's done on model.
Here is the plunk http://plnkr.co/edit/xMiwyw?p=preview
My Code:
var myApp = angular.module('myApp', ['ui.bootstrap']);
myApp.controller('ordersCtrl',
function ordersCtrl($scope, $modal){
$scope.open = function () {
var modalInstance = $modal.open({
templateUrl: 'myModalContent.html',
controller: ModalInstanceCtrl,
resolve: {
items: function () {
return $scope.items;
}
}
});
};
});
var ModalInstanceCtrl = function ($scope, $modalInstance, $http) {
$scope.dealerCount = [];
// Add a Item to the list
$scope.addItem = function () {
$scope.dealerName = dealerName;
$scope.dealerCount.push({
name: $scope.dealerName
});
// Clear input fields after push
$scope.dealerName = "";
};
$scope.ok = function () {
$modalInstance.close($scope.selected.item);
};
$scope.cancel = function () {
$modalInstance.dismiss('cancel');
};
};
Modal Template:
<div class="row" id="AddItem">
<div class="col-md-6"><p class="input-group">
<input value="" type="text" placeholder="Name of Item" ng-model="dealerName"><button ng-click="addItem()">Add to list</button></p>
</div>
</div>
<div class="row">
<tr ng-repeat="item in dealerCount" class="item-unchecked">
<td><b>Dealer:</b> {{item.name}}</td>
</tr>
</div>
works here
You have to share data between controllers in some way. The one way of doing that is to create a service
myApp.factory('data', function(){
return {
dealerCount : [],
dealerName: ''
}
});
You alse may see this video for better understanding