angular ui bootstrap - How to access modal scope without creating controller - angularjs

The docs for the $modal service say
The scope associated with modal's content is augmented with 2 methods:
-$close(result)
-$dismiss(reason)
Those methods make it easy to close a modal window without a need to create a dedicated controller.
I'm wondering how to access this scope without creating a dedicated controller.

Try this:
$scope.openModal=function(){
$scope.modalInstance=$modal.open({
templateUrl: 'xyz.html',
scope:$scope
});
}
$scope.close=function(){
$scope.modalInstance.dismiss();
};
now you can use ng-click="close()" in your temnplate file.

ı used this code.
module.service('ModalService', function ($modal) {
var modalOptions = {
backdrop: true,
keyboard: true,
modalFade: true,
templateUrl: null
};
this.show = function (customModalDefaults) {
var tempModalOptions = {};
angular.extend(tempModalOptions, modalOptions, customModalDefaults);
if (!tempModalOptions.controller) {
tempModalOptions.controller = function ($scope, $modalInstance) {
$scope.modalOptions.ok = function (result) {
$modalInstance.close(result);
};
$scope.modalOptions.close = function (result) {
$modalInstance.dismiss('cancel');
};
};
}
return $modal.open(tempModalOptions).result;
};
});
call:
var modalOptions = {
backdrop: true,
modal: true,
size: scope.options.size || 'lg',
templateUrl: '/Apps/inekle/views/common/include_modal.html?v=1',
controller: [
"$scope", "$modalInstance", function ($scope, $modalInstance) {
$scope.model = {
template: scope.options.template,
title: scope.options.title
};
$scope.close = function () {
$modalInstance.dismiss('close');
};
}
]
};
ModalService.show(this.options).then(function (model) {},function (error) { });

Related

AngularJS combine uib modal to a service

I try to open a modal with the uibModal (https://angular-ui.github.io/bootstrap/#!#%2Fmodal) but I want to have one modal with custom text inside.
i'm trying to open the modal like this :
var modalInstance = $uibModal.open({
animation: $scope.animationsEnabled,
templateUrl: '/crims/thermofluor/experiments/components/modal.html',
size: 'sm',
controller: 'ModalController',
resolve: {
content: function () {
return 'test';
}
}
});
With this controller :
angular
.module('thermofluor')
.controller('ModalController', ModalController)
ModalController.$inject = ['$uibModal', '$uibModalInstance'];
function ModalController($uibModal, $uibModalInstance, content) {
var $ctrl = this;
$ctrl.content = content;
$ctrl.ok = function () {
$uibModalInstance.close();
};
$ctrl.cancel = function () {
$uibModalInstance.dismiss();
};
}
But it seems not work, angular says that ModalController is not a function (in the modal opening ), so what can I do to get this works ?
Edit : I can do that without a ModalController :
$uibModal.open({
animation: true,
ariaLabelledBy: 'modal-title-bottom',
ariaDescribedBy: 'modal-body-bottom',
templateUrl: 'components/modal.html',
size: 'sm',
controller: function($scope) {
$scope.content = 'bottom';
}
});
But the buttons of my modal doesn't work
Edit
This finally works, here is how I do this :
function openModal(templateName, content, title){
var template = 'components/modal/'+templateName;
$uibModal.open({
animation: true,
ariaLabelledBy: 'modal-title-bottom',
ariaDescribedBy: 'modal-body-bottom',
templateUrl: template,
size: 'sm',
controllerAs: '$ctrl',
controller: function($scope, $uibModalInstance) {
$scope.content = content;
$scope.title = title;
var $ctrl = this;
$ctrl.ok = function () {
$uibModalInstance.close();
};
$ctrl.cancel = function () {
$uibModalInstance.dismiss('cancel');
};
}
});
}
Finally I found a solution, here is what I do :
I create a service ModalService :
angular.module('myModule')
.factory('ModalService', ModalService);
ModalService.$inject = ['$uibModal'];
function ModalService($uibModal) {
return new ModalService();
function ModalService(){
var service = this;
function openModal(templateName, params){
var template = 'components/modal/'+templateName;
$uibModal.open({
animation: true,
ariaLabelledBy: 'modal-title-bottom',
ariaDescribedBy: 'modal-body-bottom',
templateUrl: template,
size: 'sm',
controllerAs: '$ctrl',
controller: function($scope, $uibModalInstance) {
angular.forEach(params, function (e, key){
$scope[key] = e;
});
var $ctrl = this;
$ctrl.ok = function () {
$uibModalInstance.close();
};
$ctrl.cancel = function () {
$uibModalInstance.dismiss('cancel');
};
}
});
}
return {
openModal: openModal
};
}
}
And I use it like this in my controller :
ModalService.openModal("modal.html", {"content": "This experiment doesn't have a tm point", "title": "Tm Point"});
I can pass every variable I need and just set them in my modal html template

AngularJS: Angular UI Bootstrap, pass data from modal to controller

I have correctly setup my angular modal, now I want to pass my modal data back to my controller. I am using the below code.
First my controller calls my factory service that creates the modal popup:
$scope.mymodal = myService.openModal(data);
My service is as:
function openModal (data) {
var uData = null;
if (data) {
uData = {
userName : data.setName,
gender : data.gender
}
}
var modalInstance = $modal.open({
templateUrl: 'modal.html',
controller: 'ModalController',
backdrop: 'static',
keyboard: false,
resolve: {
data: function () {
return uData;
}
}
});
modalInstance.result.then(function () {
return;
}, function () {
});
return modalInstance;
}
See my jsfiddle here for this: http://jsfiddle.net/aman1981/z20yvbfx/17/
I want to pass name & gender that i select on my modal back to my controller, which then populates my page. Let me know what is missing here.
I updated AboutController, ModalController and myService with comments.
Main idea is return data from ModalController with close method. Fiddle
var app = angular.module('myApp', ['ui.router','ui.bootstrap']);
app.controller('IndexController', function($scope, $log) {
});
app.controller("AboutController", ['$location', '$state', '$scope', '$filter','myService', function($location, $state, $scope, $filter, myService) {
var data = "";
$scope.mymodal = myService.openModal(data);
// after modal is close, then this promise is resolve
$scope.mymodal.then(function(resp){
console.log(resp);
})
}]);
app.controller("ModalController", function($location, $state, $scope, $filter, $modalInstance) {
$scope.cancel = function () {
$modalInstance.dismiss('cancel');
$state.go('index');
};
$scope.done = function () {
// return data on close modal instance
$modalInstance.close({genger:$scope.gender,userName:$scope.userName});
};
});
app.factory('ApiFactory', function ($http) {
var factory = {};
return factory;
});
app.factory("myService",[ "$state", "$modal", "ApiFactory",
function ($state, $modal, factory) {
var service = {
openModal: openModal
};
function openModal (data) {
var uData = null;
if (data) {
uData = {
userName : data.setName,
gender : data.gender
}
}
var modalInstance = $modal.open({
templateUrl: 'modal.html',
controller: 'ModalController',
backdrop: 'static',
keyboard: false,
resolve: {
data: function () {
return uData;
}
}
});
// on close, return resp from modal
modalInstance.result.then(function (resp) {
return resp;
}, function () {
});
// return modal instance promise
return modalInstance.result;
}
return service;
}
]);
app.config(['$stateProvider', '$urlRouterProvider', function($stateProvider, $urlRouterProvider) {
$urlRouterProvider.otherwise('/index');
$stateProvider
.state('index', {
url: '^/index',
templateUrl: 'index.html',
controller: "IndexController"
})
.state('about', {
url: '^/about',
templateUrl: 'about.html',
controller: "AboutController"
})
}]);

AngularJS: controller undefined while testing directive with controllers using Jasmine

I need to test the controller my directive is using. but could not reference the controller.
directive.js
(function () {
'use strict';
angular
.module('myModule')
.directive('cabinet', function () {
return {
restrict: 'E',
replace: true,
controller: CabinetThumbnails,
controllerAs: 'ctrl',
bindToController: true,
templateUrl: 'app/components/capture/cabinet.directive.html',
scope: {
thumbnail: '='
}
};
});
function CabinetThumbnails($uibModal, cabinetService, SweetAlert,
spinner, $state, $window) {
var vm = this;
vm.showImage = showImage;
vm.deleteThumbnail = deleteThumbnail;
function showImage() {
if (vm.thumbnail.FileCategoryName === 'OpenDocument') {
$window.open(vm.thumbnail.FileUrl);
}
else {
$uibModal.open({
animation: true,
templateUrl: 'app/components/capture/cabinet.pop-up.html',
controller: ModalCtrl,
controllerAs: 'ctrl',
size: 'lg',
resolve: {
thumbnailData: function () {
return vm.thumbnail;
}
}
});
}
}
function deleteThumbnail() {
//show the popup confirmation
SweetAlert.swal({
title: 'Are you sure to delete ?',
text: 'You will not be able to recover the file once deleted !',
type: 'warning',
showCancelButton: true,
confirmButtonColor: '#DD6B55',
confirmButtonText: 'Delete',
closeOnConfirm: true
},
function (isConfirm) {
if (isConfirm) {
spinner.show();
//call the service to delete here
cabinetService.deleteCabinetFile(vm.thumbnail.CabinetFileID)
.then(function (data) {
//validate the response
if (data != null && data.returnVal === -1) {
SweetAlert.swal('You do not have access to delete ' +
'the screen shot',
'Please contact the owner of the screen shot!',
'error');
} else {
//load all the Thumbnails by reloading the page
$state.reload();
}
})
.catch(function (err) {
SweetAlert.swal('Something went wrong !',
'Please try again later !', 'error');
})
.finally(spinner.hide);
}
});
}
}
function ModalCtrl($scope, $uibModalInstance, thumbnailData,
logger, cabinetService) {
var ctrl = this;
ctrl.thumbnailData = thumbnailData;
ctrl.save = save;
ctrl.cancel = cancel;
//call this method to get executed while the directive loads to open the pop-up
getComments();
function getComments() {
cabinetService
.getComments(thumbnailData)
.then(function (data) {
ctrl.comments = data;
})
.catch(function (err) {
logger.error('Unable to get comments, Please try later !',
{ttl: 20000});
});
}
}
}());
MytestSpec.js:
'use strict';
describe('cabinet', function () {
var el,
CabinetThumbnailsController,
scope;
beforeEach(bard.appModule('myModule', bard.fakeLogger));
// Initialize the controller and a mock scope
beforeEach(function () {
bard.inject('$controller', '$compile', '$rootScope', '$q', '$uibModal',
'cabinetService', 'SweetAlert', 'spinner', '$state',
'$window');
scope = $rootScope.$new();
el = angular.element('<div cabinet></div>', {$scope: scope});
$compile(el)(scope);
//CabinetThumbnailsController = el.controller('cabinet');
CabinetThumbnailsController = $controller('CabinetThumbnails', {$scope: scope});
$rootScope.$apply();
});
it('should be initialized', function () {
expect(el).toBeDefined();
});
//controller testing
it('CabinetThumbNails controller to be initialized', function () {
expect(CabinetThumbnailsController).toBeDefined();
});
it('CabinetThumbNails controller showImage method to be called', function () {
expect(CabinetThumbnailsController.showImage).toHaveBeenCalled();
});
});
both the following statements are not working
CabinetThumbnailsController = el.controller('cabinet');
CabinetThumbnailsController = $controller('CabinetThumbnails', {$scope: scope});
and hence calling the controller methods as follows is failing too:
expect(CabinetThumbnailsController.showImage).toHaveBeenCalled();
Separated my controller to a different file and tested the Controller independently. Couldn't get an approach to test the controller along with the directive.

Error injector $uiBModalInstance

Is it possible to open and close a Modal in one controller??.
Here is my code:
ListRoleApp.controller('ListRoleController', function ($scope, $uibModal, $uibModalInstance) {
$scope.openConfirmModal = function () {
var modalInstance = $uibModal.open({
animation: true,
templateUrl: '../Template/ConfirmForm.tpl.html',
controller: 'ListRoleController',
});
};
$scope.Delete = function () {
alert('Delete')
};
$scope.Cancel = function () {
alert('Cancel')
$uibModalInstance.dismiss('cancel');
};
})
I tried and came across the below error.
Thank you
Yeah, that's possible..
If you have strict-di mode disabled on your AngularJS app you can do it like this:
var modalInstance = $uibModal.open({
animation: true,
templateUrl: '../Template/ConfirmForm.tpl.html',
controller: function($scope, $uibModalInstance) {
$scope.Delete = function () {
alert('Delete')
};
$scope.Cancel = function () {
alert('Cancel')
$uibModalInstance.dismiss('cancel');
};
},
});
If strict-di mode is enabled just define your controller in a separate variable in your ListRoleController and inject the $scope and $uibModalInstance:
var modalController = function ($scope, $uibModalInstance) {
$scope.yes = function() {
$uibModalInstance.close();
};
$scope.cancel = function() {
$uibModalInstance.dismiss('cancel');
};
};
modalController.$inject = ['$scope', '$uibModalInstance'];
var modalInstance = $uibModal.open({
animation: true,
templateUrl: '../Template/ConfirmForm.tpl.html',
controller: modalController,
});

use a bootstrap modal without making a seperate controller

I am using a bootstrap modal
Controller.js -
$scope.open = function() {
var modalInstance = $modal.open({
animation: true,
templateUrl: 'views/template.html',
controller: 'controller2',
resolve: {
items: function() {
return $scope.values;
}
}
});
modalInstance.result.then(function(values) {
$scope.new_value = values;
}, function() {
});
};
I don't want to create a new controller since the modal should show values which are constantly changing in the current controller. What should I pass in place of controller2 if I modal to be in the same controller?
You could use the scope option instead of the controller:
$scope.open = function() {
var modalInstance = $modal.open({
animation: true,
templateUrl: 'views/template.html',
scope: $scope,
resolve: {
items: function() {
return $scope.values;
}
}
});
modalInstance.result.then(function(values) {
$scope.new_value = values;
}, function() {
});
};

Resources