Angular UI Bootstrap Modal, bind model changes immediately - angularjs

I am trying to use Angular UI Bootstrap Modal. And I want to have the changes to the model to be shown immediately.
This is the controller:
$scope.testInputField = "";
$scope.showModal= function () {
var modalInstance = $modal.open({
templateUrl: 'partials/modal.html',
controller: 'ModalController',
resolve: {
inputTest: function () {
return $scope.testInputField;
}
}
});
modalInstance.result.then(function () {
// Do stuff
}, function () {
console.log("Some Error");
});
}
I have testInputField model also in my partial view.
And this is the the modal controller
controller('ModalController', [ '$scope', '$modalInstance', 'inputTest', function ($scope, $modalInstance, inputTest) {
$scope.inputTest = angular.copy(inputTest);
$scope.keyPressed = function (key) {
$scope.inputTest+= key;
console.log($scope.inputTest);
};
} ])
So basically what I want whenever changes are made to with the keyPressed method, the modal in my main controller to be changed at the same time. Is there a possibility to accomplish this with UI bootstrap modals current code

For this remove angular.copy method and try again. As it remove the data binding of the object.

Related

Firing event from dynamically opened controller to parent controller in Angular js

I am developing an Web Application using Angular JS. I am new to Angular JS. in my app I am using bootstrap.ui JS for Angular js. But I am having a problem with bootstrap modal controller. I open the bootstrap modal with new controller instance. Then I want to fire event back to parent controller when a button of modal is pressed.
I open Bootstrap modal when a button is clicked like below in a controller
var app = angular.module('memeApp',['ngRoute','ui.bootstrap','blockUI','ngFileUpload'],function($interpolateProvider) {
$interpolateProvider.startSymbol('<%');
$interpolateProvider.endSymbol('%>');
});
app.controller('DeleteConfirmModalController', ['$scope','$modalInstance','data',function ($scope, $modalInstance,data) {
$scope.closeDeleteConfirmModal = function () {
$modalInstance.dismiss('cancel');
};
$scope.deleteData = function()
{
//I want to call deleted function of DefaultController that opened current controller.
}
}]);
app.controller('DefaultController', ['$scope', 'Upload', '$timeout', '$http','$modal', function ($scope, Upload, $timeout , $http, $modal) {
$scope.deleted = function(param)
{
alert('deleted')
}
$scope.deleteTemplate = function(id,url)
{
var modalInstance = $modal.open({
controller: 'DeleteConfirmModalController',
templateUrl: $scope.deleteConfirmModalUrl,
resolve: {
data: function () {
return { id: id, url: url };
}
}
});
}
}]);
Let me explain my code above. When a user click a button in DefaultController, deleteTemplate function will be called. So that function open bootstrap modal creating new instance of DeleteConfirmModalController. When user click the delete button of bootstrap modal, deleteData function of modal controller will be called.
So I commented what I want to do inside that function. I want to call deleted function inside DefaultController. How can I call that function of parent controller from modal controller?
You can do so easily by passing the function you want to run as a callback to the modal.
vm.deleteData = function() {
// do something
}
Then pass to
var modalInstance = $uibModal.open({
animation: true,
templateUrl: 'vm.deleteConfirmModalUrl',
controller: 'DeleteConfirmModalController',
controllerAs: 'vm',
resolve: {
deletedCallback: function() {
return vm.deleted; // notice that I am passing a reference of `deleted` function
}
}
});
Then, inside the modal controller I wire an invocation to this callback function by a button click
.controller('ModalInstanceCtrl', function ($uibModalInstance, deletedCallback) {
// this will run on an ng-click
vm.runDeleted = function() {
if (angular.isFunction(deletedCallback)) {
deletedCallback("me");
}
}
...
}
I use angular.isFunction to test if the reference I passed to the modal controller is indeed of that of a function, and if it is, I run it, and I pass some value (in this case the string me) into the callback.
This code will run on the DeleteConfirmModalController controller.
Example plunk

How to see whether modal is open in Angular UI Bootstrap

I'm using Angular UI Bootstrap. If a modal is open, I'd like to display true. If it's not open, I'd like to display false. Is there a way to do this within the HTML?
I tried using the following code, but it's wrong:
<code>myForm.$modalStack.opened={{myForm.$modalStack.opened}}</code>
Any thoughts on how to do this correctly?
Below the relevant code I'm using to trigger the modal:
HTML:
<button ng-click="myForm.agreement()">
Code in Controller:
.controller('MyFormCtrl',
function ($location, $stateParams, $modal, $scope, $http) {
var myForm = this;
// . . .
myForm.agreement = agreement;
function agreement() {
$modal.open({
templateUrl: 'views/agreement.html'
})
});
The opened property returned by $modal.open is a promise you can hook into.
So, using their example, see here - http://plnkr.co/edit/PsEqTIy8CDUU88HMLxbC?p=preview
$scope.modalOpen = false;
$scope.open = function (size) {
var modalInstance = $modal.open({
animation: $scope.animationsEnabled,
templateUrl: 'myModalContent.html',
controller: 'ModalInstanceCtrl',
size: size,
resolve: {
items: function () {
return $scope.items;
}
}
});
modalInstance.opened.then(function () {
$scope.modalOpen = true;
});
// we want to update state whether the modal closed or was dismissed,
// so use finally to handle both resolved and rejected promises.
modalInstance.result.finally(function (selectedItem) {
$scope.modalOpen = false;
});
};
You want to call the promises and then do whatever you need. .opened is a promise for when the modal opens, and .result is a promise for when the modal closes. So using this idea, you would use $scope.modalOpen as your boolean.

Passing value to modal scope in angular ui-bootstrap

I have a form setup in angular and am using ui-bootstrap for a modal dialog that appears before submission is complete. My site is setup in Sharepoint and uses a context to determine if they are on English or Spanish version of the site and display the proper language content. I want to pass the bool value IsInEnglish to the modal to display the correct <div> but I am not finding a solution to pass this value to the scope of the modal.
$scope.continue = function () { //this is off an ng-click on a button
var modalInstance = $modal.open({
templateUrl: '_layouts/Applications/VolunteerApp/modal/myModal.html',
controller: 'vAppController'
});
modalInstance.opened.then(function () {
$scope.modalIsInEnglish = IsInEnglish;
});
};
Add a resolve to $modal's instantiation object:
var modalInstance = $modal.open({
templateUrl: '_layouts/Applications/VolunteerApp/modal/myModal.html',
controller: 'vAppController',
resolve: {
myVar: function() {
return someVal;
}
}
});
and then pass someVal as an argument of the function that invokes the modal:
$scope.continue = function (someVal)
To access someVal in the modal controller, pass it in as an argument for the modal controller:
function myModalController($scope, someVal) { // do stuff }

Close only one current modal using $modalStack in Ui Bootstrap

I'm using a solution found here: How to close Angular UI Modal from anywhere
to close a UI bootstrap modal that I'm using as an HTTP interceptor to show loading.
However, this solution closes ALL open modals since $modalStack.dismissAll() is being used. How do I remove only the modal that's open with the loading. Here's my code:
app.factory('loadingModal', ['$modal', '$modalStack', function($modal, $modalStack) {
return {
trigger: function(template) {
$modal.open({
windowClass: 'modal fade loading-modal',
templateUrl: '/assets/partials/modals/loadingModal.html',
backdrop: 'static',
controller: function($scope, $modalInstance) {
$scope.ok = function() {
$modalInstance.close($scope.selected.item);
};
$scope.cancel = function() {
$modalInstance.dismiss('cancel');
};
}
});
},
close: function(reason) {
$modalStack.dismissAll(reason);
// $modal.close();
}
};
}])
Not totally clear how you are using this in interceptor but you should be able to return the instance from trigger and then use instance.dismiss()
app.factory('loadingModal'.....
return {
trigger: function(template) {
// return this instance
return $modal.open({.....
......
}
Then store instance wherever you intialize trigger() in interceptor
var modal = loadingModal.trigger('tmpl.html');
Then to close
modal.dismiss();
Of course you could store this instance in service and create a method to close it with a service method also

AngularUI Bootstrap Modal Open event

I'm invoking a bootstrap modal dialog through a link.
I want to start a timer in the angular controller when the dialog pops up. How do I detect the dialog open event in the angular controller to start the timer?
If I start timer in the scope like this,
app.controller('myctrl',
['$scope', '$window', '$timeout', 'svc',
function ($scope, $window, $timeout, svc) {
$scope.countdown = 10;
$scope.runCounter = function () {
$scope.countdown -= 1;
if ($scope.countdown > 0)
$timeout($scope.runCounter, 60000);
}
$scope.runCounter();
}]);
the timer starts when the application starts. I want the timer to start only when the dialog opens.
Thanks.
Check this out.
var modalInstance = $modal.open({...});
modalInstance.opened.then(function() {
alert("OPENED!");
});
The $modal.open() returns an object that, among other properties contains the opened promise, to be used as above.
I assume that you are using modals from http://angular-ui.github.io/bootstrap/.
If you look closely you will see that the component expose a promise that will be resolved when the dialog is opened. Which is what you will need to use. You can do something like that in the controller where the modal is created:
$scope.runCounter = function () {
$scope.countdown -= 1;
if ($scope.countdown > 0)
$timeout($scope.runCounter, 60000);
}
//Creating the dialog
var modalInstance = $modal.open({
templateUrl: 'myModalContent.html',
controller: ModalInstanceCtrl
}
});
//Add a function for when the dialog is opened
modalInstance.opened.then(function () {
$scope.runCounter
});
See working plunker here
var modalInstance = $modal.open({
templateUrl: '../augustine_app/templates/program_purchase_popup.html',
backdrop: 'static',
controller: function ($scope, $modalInstance) {
$scope.cancel = function () {
$modalInstance.dismiss('cancel');
};
}
});
if (navigator.userAgent.match(/iPhone|iPad|iPod/i)) {
modalInstance.opened.then(function () {
var modal;
var getModalInterval = function () {
modal = document.getElementsByClassName('modal')[0];
if (modal) {
clearInterval(getModal);
modal.style.marginTop = window.screenTop + 'px';
modal.style.height = 'auto';
modal.style.position = 'absolute';
modal.style.overflow = 'visible';
}
};
modal = document.getElementsByClassName('modal')[0];
if (!modal) {
var getModal = setInterval(getModalInterval, 2000);
}
});
}
};
Unfortunatly the open.then(func) runs before the freaking modal is actually in the DOM. Hence the setInterval.
here is some non jQuery angular code.
For my case, I need to be able to detect when modal is opened inside the modal controller itself.
At first opened promise was resolved even though the modal hasn't been loaded in the DOM yet. By wrapping the call inside a $timeout, opened promise is now resolved after the modal is loaded to the DOM.
$modal.open({
templateUrl: 'modalTemplate.html',
controller: 'modalCtrl'
});
// inside modalCtrl
angular.controller('modalCtrl', ['$modalInstance', '$timeout', function($modalInstance, $timeout) {
$timeout(function() {
$modalInstance.opened.then(function() {
//do work
});
});
}]);

Resources