Closing all the modal bootstrap pop up in Angular JS - javascript

I want to close all the modal pop up boxes when a user clicks on a close button of the final confirmation modal popup.
But the modal windows that are open do belong to different controllers. Here is the snippet :
function getQuickCasePopup($scope, $uibModal, $rootScope) {
var templateUrl = BasePath + 'App/Transaction/Views/common/QuickCaseSearch.tpl.html';
var controller = 'QuickCaseSearchCtrl';
OpenModal($scope, $uibModal, null, templateUrl, controller, null, null, '', $rootScope);
}
function getAddCasePopup($scope, $uibModal, $rootScope) {
var templateUrl = BasePath + 'App/Transaction/Views/common/CreateCase.tpl.html';
var controller = 'AddCaseCtrl';
OpenModal($scope, $uibModal, null, templateUrl, controller, null, null, '', $rootScope);
}
function getAdvanceCasePopup($scope, $uibModal, $rootScope) {
var templateUrl = BasePath + 'App/Transaction/Views/common/AdvanceCaseSearch.tpl.html';
var controller = 'AdvanceCaseCtrl';
OpenModal($scope, $uibModal, null, templateUrl, controller,null, null, 'lg', $rootScope);
}
function OpenModal($scope, $uibModal, $stateParams, templ, ctrl, grid, row, size, $rootScope) {
var CssClass = '';
if (size === 'lg') {
CssClass = 'app-modal-window';
}
var ModalInstance = ModalInstance || $uibModal.open({
animation: $scope.animationsEnabled,
templateUrl: templ,
controller: ctrl, // Logic in instantiated controller
windowClass: CssClass
});
And the confirmation pop - up code looks like :
$("#iConfirmationModal").modal();
$("#iConfirmationModal").on('hidden.bs.modal', function () {
//$(".app-modal-window").dialog("close"); //Did not work
$state.go('transaction.search', {});
});
So I want to close all the modal pop-ups and then redirect . Can I achieve the same ?

The modal is a singleton object so you can call $scope.$close() and it all close all modal instance

You may have multiple options,
create a service which will manage all modal status.
Use $emit\$broadcast for notifications.
use third part libraries like amplifyjs and use there pub\sub operations.

Related

Modal in Angular does not work. Unhandled rejection {}

I want to create a modal (dialog). I have followed examples on official bootstrap documentation but I stuck. When I am trying to create modal I receive an error
angular.min.js:122 Possibly unhandled rejection: {}
mainController:
angular
.module('app')
.controller('tlmController', function($scope, $http, $timeout, $uibModal, DTOptionsBuilder, DataLoader, TestLines) {
$scope.openTestLineDetails = function(id) {
var modalInstance = $uibModal.open({
size: 'lg',
controller: 'testlineDetailsController',
templateUrl: 'app/client/layout/testlinedetails.tpl.html',
resolve: {
testLineId: function() {
return id;
}
}
});
};
})
and TestlineDetailsController:
angular
.module('app')
.controller('testlineDetailsController', function($scope, $modalInstance, testLineId) {
});
What is wrong with this code? I am using $uibModal ($modal service does not exist) in main controller. When I replace $modalInstance by $uibModalInstance I receive an error too (service $uibModalInstance does not exist), so I have to use $uibModal with $modalInstance. Strage but true.
you can write below code in app.config
app.config(['$qProvider', function ($qProvider) {
$qProvider.errorOnUnhandledRejections(false);
}]);
First of all, check your modal controller script is appended to the main HTML file and if its appended(appears) in the browser (In Chrome, open web developer tools with F12 keyboard button then open the "Elements" tab button) (This is in case you are using some scaffolding tool like generator-angular from Yeoman's team, remember to clear cache in order to get the latest update from your code), because I had the same problem :( and I was reviewing constantly what was wrong with my code then I found out that the browser was not appending the latest script I made (Modal controller), so my code was like yours, but taking your code example:
<!-- In your index.html file, check for this script being appended in your browser -->
<script src="testlineDetailsController.js"></script>
//In your parent controller
angular
.module('app')
.controller('tlmController', function($scope, $http, $timeout, $uibModal, DTOptionsBuilder, DataLoader, TestLines) {
$scope.openTestLineDetails = function(id) {
var modalInstance = $uibModal.open({
size: 'lg',
controller: 'testlineDetailsController',
templateUrl: 'app/client/layout/testlinedetails.tpl.html',
resolve: {
testLineId: function() {
return id;
}
}
});
};
})
Secondly, make sure you are implementing at least one method from the modal instance service in the modal controller: EDIT: (This is optional, you can hide the modal using the backdrop property from the modal option object)
//In your modal controller
angular.module('app').
controller('testlineDetailsController', function ($scope, $uibModalInstance, testLineId) {
//In case you have the ok and cancel buttons in your modal template
$scope.id = testLineId;
$scope.ok = function () {
$uibModalInstance.close();
};
$scope.cancel = function () {
$uibModalInstance.dismiss('cancel');
};
});
After this, your app should be working.
Now, there is another alternative to get this issue solved, you can directly write the controller function in the property of the modal options object:
//In your parent controller
angular
.module('app')
.controller('tlmController', function($scope, $http, $timeout, $uibModal, DTOptionsBuilder, DataLoader, TestLines) {
$scope.openTestLineDetails = function(id) {
var modalInstance = $uibModal.open({
size: 'lg',
//write an anonymous function instead of naming the controller name.
controller: function ($scope, $uibModalInstance, testLineId) {
$scope.id = testLineId;
$scope.ok = function () {
$uibModalInstance.close();
};
$scope.cancel = function () {
$uibModalInstance.dismiss('cancel');
};
},
templateUrl: 'app/client/layout/testlinedetails.tpl.html',
resolve: {
testLineId: function() {
return id;
}
}
});
};
})
This alternative should work also in your app. So I hope this explanation helps you to solve the issue you have.

Pass data from an Angular modal's controller back to the main controller

Here is the thing. I am not able to pass data from angular modal back to the controller where i need it. the codes given below.
Controller side
'use strict'
var DataMod = angular.module('Data', ["angularGrid", 'ui.bootstrap.contextMenu', 'ui.bootstrap']);
DataMod.controller('DataController', ['$scope', '$compile', '$uibModal', '$log','$rootScope', '$http', function ($scope, $compile, $uibModal,$log, $rootScope, $http, ngUtilityService) {
//user first clicks on Add button. A modal opens up. ModalInstanceCtrl is the controller used.
$scope.adduser = function () {
var modalInstance = $uibModal.open({
templateUrl: 'myModalContent.html',
controller: ModalInstanceCtrl
});
//response data should be available here.
};
var ModalInstanceCtrl = function ($scope, $uibModalInstance) {
//ajax call is made is inside this controller and i get a response.
//this response is an object. i need to pass this object back to the adduser function. mentioned it above.
};
}
]);
As you can see above, there is the main controller. I have used a modal inside there which has its own controller. I make ajax call inside that modals controller and get a response back.
I want that response as a result to be available back at the adduser function so that i can work with that data. However, it seems that once the adduser function starts, it goes to the ModalInstanceCtrl and ends its execution there. It doesnt come back to the adduser function at all. I need a way to get back to the adduser function.
Can anyone let me know how to achieve this. Also how to pass the object response from ModalInstanceCtrl to the main controller inside adduser function.
It looks like you are using the Angular Bootstrap Modal, yes? First, I would set it up so that the modal controller is separated out from the main controller. Second, you are missing the promise needed to pass the response from the modal to the main controller. You can read about the return modal instance in the docs here: https://angular-ui.github.io/bootstrap/#/modal
This is the example code from the Angular Bootstrap plunkr: http://plnkr.co/edit/nGjBtMp33pFDAQ6r7Tew?p=info
angular.module('ui.bootstrap.demo', ['ngAnimate', 'ui.bootstrap']);
angular.module('ui.bootstrap.demo').controller('ModalDemoCtrl', function ($scope, $uibModal, $log) {
$scope.items = ['item1', 'item2', 'item3'];
$scope.animationsEnabled = true;
$scope.open = function (size) {
var modalInstance = $uibModal.open({
animation: $scope.animationsEnabled,
templateUrl: 'myModalContent.html',
controller: 'ModalInstanceCtrl',
size: size,
resolve: {
items: function () {
return $scope.items;
}
}
});
modalInstance.result.then(function (selectedItem) {
$scope.selected = selectedItem;
}, function () {
$log.info('Modal dismissed at: ' + new Date());
});
};
$scope.toggleAnimation = function () {
$scope.animationsEnabled = !$scope.animationsEnabled;
};
});
// Please note that $uibModalInstance represents a modal window (instance) dependency.
// It is not the same as the $uibModal service used above.
angular.module('ui.bootstrap.demo').controller('ModalInstanceCtrl', function ($scope, $uibModalInstance, items) {
$scope.items = items;
$scope.selected = {
item: $scope.items[0]
};
$scope.ok = function () {
$uibModalInstance.close($scope.selected.item);
};
$scope.cancel = function () {
$uibModalInstance.dismiss('cancel');
};
});

Refresh data originally passed into modalInstrance in AngularJS

Using Angular - UI Bootstrap
I am passing data into a modalInstance like the below. In the modal, users have the ability to create new items. On the save button press, a new item is sent to the server. I need the ability to refresh the modal instance with the updated data from $scope.items. Note, the modal doesn't close on the save, so I can't just re-open it. Any help would be greatly appreciated.
$scope.items = ['item1', 'item2', 'item3'];
$scope.open = function (size) {
var modalInstance = $modal.open({
templateUrl: 'myModalContent.html',
controller: 'ModalInstanceCtrl',
resolve: {
items: function () {
return $scope.items;
}
}
});
modalInstance.result.then(function () {
// post updated $scope.items to server
// get fresh $scope.items from server
// notify modal of the updated items
}, function () {
});
};
});
You can try just to create scope for your $modalInstance as a child of current $scope like this:
var modalInstance = $modal.open({
templateUrl: 'myModalContent.html',
controller: 'ModalInstanceCtrl',
scope: $scope
});
So now after add some item to your items everything will work fine.
For more info you can take a look at description of $modal directive on the angular bootstrap page:
scope - a scope instance to be used for the modal's content (actually the $modal service is going to create a child scope of a provided scope). Defaults to $rootScope
Demo: http://plnkr.co/edit/khzNQ0?p=preview
Hope, it will resolve your problem ;)

Pass an AngularJS $scope variable to new controller when link clicked

I have an app that uses dynamic routing to load modal windows, with each window displaying one "activity" object from a JSON file. Currently I'm using the route to determine which card is visible, and then calling a data service to fill in the data based on a match with the route name.
But I don't like this solution, as it isolates my current card from the context of the array. I would far prefer to be able to pass the card object from the template, because then I will know what the $index is, which I can then use to navigate to "prev" and "next" elements.
If I have this mark-up:
<div ng-controller="MenuCtrl">
<ul class="menu">
<li ng-repeat="card in cards">
{{ card.shortName }}
</li>
</ul>
</div>
Which triggers this $routeProvider:
$routeProvider
.when('/page/:name', {
templateUrl : 'modalContainer',
controller : 'ModalContainerCtrl'
})
Which brings up this controller:
.controller('ModalContainerCtrl',['$scope', '$modal', '$route', function($scope, $modal, $route) {
var modalInstance = $modal.open({
templateUrl : '../assets/templates/modal.html',
controller: 'ModalCtrl'
});
$scope.activity = $route.current.pathParams.name;
console.log($scope.activity);
//Modal controls
$scope.close = function () {
console.log("close!");
$modalInstance.close();
};
}])
is there any way I can pass the card object to ModalContainerCtrl via this routing or any other means?
You can pass a scope object to a modal window controller using the resolve (definition of resolve Members that will be resolved and passed to the controller as locals; it is equivalent of the resolve property for AngularJS route). So in your case it can be done like this:
.controller('ModalContainerCtrl',['$scope', '$modal', '$route', function($scope, $modal, $route) {
//your card object
$scope.card = '';
var modalInstance = $modal.open({
templateUrl : '../assets/templates/modal.html',
controller: 'ModalCtrl',
resolve: {
card: function () {
return $scope.card;
}
}
});
$scope.activity = $route.current.pathParams.name;
console.log($scope.activity);
//Modal controls
$scope.close = function () {
console.log("close!");
$modalInstance.close();
};
}])
and in the modal controller:
var ModalCtrl = function ($scope, $modalInstance,card) {
//Modal controls
//card now can be used over here
$scope.close = function () {
console.log("close!") //This will now run
modalInstance.close();
};
}

Angular-ui modal issue

I'm trying to include an angular-ui modal in my web application but am having issues with getting everything set up.
The documentation indicate that you can use $modalInstance to inject the child controller into the parent controller but I don't quite understand how to go about doing so.
Here is the current code (it is straight from the modal demo from the documentation):
angular.module('myApp.controllers', []).
controller('addContent', function ($scope, $http, $modal, $log){
//modaltest
$scope.items = ['item1', 'item2', 'item3'];
$scope.addTerm = function () {
var newTerm = $modal.open({
templateUrl: 'newTermModal.jade',
controller: newTerms,
resolve: {
items: function () {
return $scope.items;
}
}
});
newTerm.result.then(function (selectedItem) {
$scope.selected = selectedItem;
}, function () {
$log.info('Modal dismissed at: ' + new Date());
});
};
}).
controller("newTerms",function($scope, $modalInstance, items){
$scope.items = items;
$scope.selected = {
item: $scope.items[0]
};
$scope.ok = function () {
$modalInstance.close($scope.selected.item);
};
$scope.cancel = function () {
$modalInstance.dismiss('cancel');
};
});
When I run the app like it is now and click the button to open the modal (addTerm function) the app crashes with the error "ReferenceError: newTerms is not defined."
As I mentioned above, the angular-ui site indicates you can inject a controller with $modalInstance but I have not been able to figure out how.
a
Any help would be greatly appreciated!
EDIT
After adding the quotation marks on the pathname as suggested by Chandermani, it seems the modal is loading in the current page rather than the specified template.
I've changed the path to the following: templateUrl:
$scope.addTerm = function () {
var newTerm = $modal.open({
templateUrl: './views/partials/newTermModal.jade',
controller: 'newTerms',
resolve: {
items: function () {
return $scope.items;
}
}
});
A screenshot of the issue follows:
Any idea what could be causing this?
Well you can pass the controller as a string value. I took the default demo sample for modal and changed it to pass controller name instead of controller itself.
See my plunker http://plnkr.co/edit/jpJX4WvHw0SSYm3pAAzq?p=preview
So something like this
controller: 'newTerms',
should work.
I got the same problem, the modal loads main HTML file but not template.
My previous configuration was:
opens dialogs but dialog content is main HTML (like on your pic)
$scope.opts = {
backdrop: true,
backdropClick: true,
dialogFade: false,
keyboard: true,
templateUrl : 'app/reports/modalContent.html',
controller : 'ModalInstanceCtrl',
resolve: {}
};
works as expected
$scope.opts = {
backdrop: true,
backdropClick: true,
dialogFade: false,
keyboard: true,
templateUrl : '/app/reports/modalContent.html',
controller : 'ModalInstanceCtrl',
resolve: {}
};
Sounds like if you put wrong templateUrl, it by default uses main page HTML.
Be sure that you have right path for templateUrl
Hope it will help,
Have you tried to declare a dependency of 'ui.bootstrap' module? Like this:
angular.module('myApp.controllers', ['ui.bootstrap'])
Happened to me today, too. The templateUrl in the controller must match the id for the modal in the html file.
You need to define the newTerms controller before your other controller. Or you can change the code and just create a function inside your main controller with the name newTerms and remove the quotation marks for the name of your controller in your modal.
$scope.addTerm = function () {
var newTerm = $modal.open({
templateUrl: './views/partials/newTermModal.jade',
controller: newTerms,
resolve: {
items: function () {
return $scope.items;
}
}
});
var newTerms = function($scope, $modalInstance, items){
$scope.items = items;
$scope.selected = {
item: $scope.items[0]
};
$scope.ok = function () {
$modalInstance.close($scope.selected.item);
};
$scope.cancel = function () {
$modalInstance.dismiss('cancel');
};
}

Categories

Resources