Calling Controller From Within a Controller - angularjs

I have two controller, one using the UI Bootstrap modal. When using flat function (like) it works, but when I try and add them to my modules it does not work, giving an error: Unknown provider: ModalInstanceCtrlProvider <- ModalInstanceCtrl
What is the correct fashion to do this? Code follows:
angular.module( 'fb.controllers', [] ).controller( 'ModalInstanceCtrl', function( $scope, $modalInstance, data ) {
$scope.data = data;
$scope.ok = function () { $modalInstance.close(); };
$scope.cancel = function () { $modalInstance.dismiss(); };
});
angular.module( 'fb.controllers' ).controller( 'shortLinkModal', ['ModalInstanceCtrl', function( $scope, $modal, ModalInstanceCtrl ) {
$scope.open = function ( url, title ) {
var modalInstance = $modal.open( {
templateUrl: 'myModalContent.html',
controller: ModalInstanceCtrl,
resolve: { data: function () { return { title: 'Short Link', url: url, bb: '[url=' + url + ']' + title + '[/url]' } } }
});
};
}]);
On further investigation, it appears that the controller: ModalInstanceCtrl part is expecting a function.

If you add your modal controller to module, you need to use string literal, like this
controller: 'ModalInstanceCtrl',

Controllers can't be injected into other controllers.
Simply pass the controller name, and the $modal.open() method will instantiate it:
var modalInstance = $modal.open( {
controller: 'ModalInstanceCtrl',
...
});

Related

How to use one controller inside another one

I would like to use one controller inside another one. I have found that I could use angular service $controller.
This is what I have tried:
.controller(
'UnplannedTasksController',
[
'$location',
'$uibModal',
'$controller',
'unplannedTasksService',
'messages',
function($location, $uibModal, $controller, unplannedTasksService, messages) {
var ctrl = this;
var modalInstanceCtrl = $controller('ModalInstanceCtrl');
this.openModal = function(unplannedTask) {
var modalInstance = $uibModal.open({
animation: false,
templateUrl: 'unplanned-tasks/unplanned-tasks-modal.html',
controller: modalInstanceCtrl,
controllerAs: 'mdCtrl',
size: 'lm',
resolve: {
object: function() {
return unplannedTask;
},
title: function() {
return messages.unplannedTasks.deleteTitle;
},
question: function() {
return messages.unplannedTasks.deleteQuestion + unplannedTask.partner.name;
}
}
});
modalInstance.result.then(function(unplannedTask) {
ctrl.display.getUnplannedTasksBusyPromise = unplannedTasksService.removeUnplannedTask(unplannedTask.id).then(function(data) {
ctrl.searchUnplannedTasks();
});
});
};
}])
This ModalInstanceCtrl is in another file and look like this:
.controller('ModalInstanceCtrl', function($modalInstance, object, title, question) {
var ctrl = this;
this.object = object;
this.title = title;
this.question = question;
this.ok = function() {
$modalInstance.close(ctrl.object);
};
this.cancel = function() {
$modalInstance.dismiss('cancel');
};
})
But I am getting an error:
"Error: [$injector:unpr] Unknown provider: $modalInstanceProvider <- $modalInstance <- ModalInstanceCtrl ..."
Could you please advise. Thank you.
[EDIT]
Anyone? Please ...
Best regards,
mismas
According to the Angular-UI documentation, you do not need to use $controller. You just have to tell the controller name the the $uibModal service, as a simple string.
In your case:
var modalInstance = $uibModal.open({
controller: 'modalInstanceCtrl'
// + more params
});

Push and pull data into ui.bootstrap modal

I have set up a plunkr here:
http://plnkr.co/edit/NdHqQJ?p=preview
I'm trying to push and pull the form data into the modal window when you click on the task. I have read that you can do this with the "resolve" property (seen below) of the modal but I have been unable to get it to actually work. Any insight would be greatly appreciated.
var modalInstance = $modal.open({
templateUrl: 'editTask.html',
controller: 'ModalInstanceCtrl',
size: size,
scope: $scope,
resolve: {
items: function () {
return $scope.items;
}
}
});
Please let me know if you need more details!
If you want to use resolve (you can) the nit will be like this for example:
$scope.open = function(size, task) {
var modalInstance = $modal.open({
templateUrl: 'editTask.html',
controller: 'ModalInstanceCtrl',
size: size,
resolve: {
task: function() {
return task
}
}
});
};
HTML:
<a ng-click="open('lg', noStoneTask)" style="cursor:pointer" tooltip-placement="top" tooltip="Open Task">{{noStoneTask.taskSubject}}</a>
Demo: http://plnkr.co/edit/NA71479d04Yw7hh2Twx8?p=preview
You have to pass the scope you want to resolve (pass to the modal) in the resolve. and resolve it in the modal controller.
Is this what you want to achieve?
http://plnkr.co/edit/Q0G79C?p=preview
I modified the modal to pass the noStoneTasks scope to the modal
//modal
$scope.open = function (size) {
var modalInstance = $modal.open({
templateUrl: 'editTask.html',
controller: 'ModalInstanceCtrl',
size: size,
resolve: {
noStoneTasks: function () {
return $scope.noStoneTasks;
}
}
});
};
I also modify the scope when the user click ok.
uxModule.controller('ModalInstanceCtrl', function ($scope, $modalInstance, noStoneTasks) {
$scope.ok = function () {
noStoneTasks[0].actHours++;
$modalInstance.close('save');
};
$scope.cancel = function () {
$modalInstance.dismiss('cancel');
};
});

Angular Modal with Dynamic Content that has Custom Directives

I am trying to display a dynamic form which contains custom directives as a modal. I have tried to use ng-bind-html but the html content that has custom directive shows up empty and throws error "The sanitizer was unable to parse the following block of html:"
Here is the running demo. Please advise.
angular.module('ui.bootstrap.demo', ['ngAnimate', 'ui.bootstrap', 'ngSanitize']);
angular.module('ui.bootstrap.demo').controller('ModalDemoCtrl', function ($scope, $modal, $log) {
$scope.textvalue = "";
$scope.cbvalue = "";
});
// Please note that $modalInstance represents a modal window (instance) dependency.
// It is not the same as the $modal service used above.
angular.module('ui.bootstrap.demo').controller('ModalInstanceCtrl', function ($scope, $modalInstance, items) {
$scope.items = items;
$scope.textvalue;
$scope.ddvalue;
$scope.selected = {
item: $scope.items[0]
};
$scope.ok = function () {
$modalInstance.close($scope.selected.item);
};
$scope.cancel = function () {
$modalInstance.dismiss('cancel');
};
});
angular.module('ui.bootstrap.demo').directive('customTextinput', function(){
return {
restrict: "EA",
scope: {
label: "=",
fieldvalue: "="
},
templateUrl: "customti.html",
controller: function($scope, $log){
}
}
})
angular.module('ui.bootstrap.demo').directive('customDropdown', function(){
return {
restrict: "EA",
scope: {
label: "="
},
templateUrl: "customcb.html",
controller: function($scope, $modal, $sce){
$scope.showModal = function(){
var modalInstance = $modal.open({
animation:true,
templateUrl: 'modaldemo.html',
backdrop: 'static',
controller: function($scope, $log, $modalInstance){
$scope.myContent = '<custom-textinput label="\'Text Input\'" ng-model="textvalue"';
//$scope.myContent = "<p>Hello World</p>";
$scope.ok = function () {
$modalInstance.close('');
}
$scope.cancel = function () {
$modalInstance.dismiss('cancel');
}
}
})
}
}
}
})
You need module called ngSanitize take a look on angular docs here
https://docs.angularjs.org/api/ngSanitize
After installing this .You can use $sce service like this
var cleanHtml = $sce.trustAsHtml(html);
It will solve sanitizer errors.Also do not forget to inject it into direcitve.

AngularUI modal custom scope

I wanted to define a custom scope for the modal (I don't want to use dependency injection for reasons) I am using in my project, but I'm getting an error whenever I define a scope in $modal.open. Here is the plunk I created from the example on AngularUI's website: http://plnkr.co/edit/rbtbpyqG7L39q1qYdHns
I tried debugging and saw that (modalOptions.scope || $rootScope) returns true with a custom scope and since true (obviously) doesn't have a $new() function defined, an exception is thrown.
Any thoughts?
You'll have to pass a scope instance:
var modalInstance = $modal.open({
animation: $scope.animationsEnabled,
templateUrl: 'myModalContent.html',
controller: 'ModalInstanceCtrl',
size: size,
resolve: {
items: function () {
return $scope.items;
}
},
scope: $scope
});
You can also pass your own custom scope if you don't want to use the controller's scope, working plnkr:
http://plnkr.co/edit/1GJTuVn45FgPC3jIgyHv?p=preview
First Way
To pass a variable to a modal you can do it in this way
var modalInstance = $modal.open({
animation: $scope.animationsEnabled,
templateUrl: 'myModalContent.html',
controller: 'ModalInstanceCtrl',
size: size,
resolve: {
items: function () {
return $scope.items;
},
test: function(){
return $scope.test; //This is the way
}
}
});
In your modal you have this
angular.module('ui.bootstrap.demo').controller('ModalInstanceCtrl', function ($scope, $modalInstance, items, test) {
$scope.items = items;
$scope.test = test; // And here you have your variable in your modal
console.log("Test: " + $scope.test)
$scope.selected = {
item: $scope.items[0]
};
$scope.ok = function () {
$modalInstance.close($scope.selected.item);
};
$scope.cancel = function () {
$modalInstance.dismiss('cancel');
};
});
Here you have your own example in Plunker
Second Way
var modalInstance = $modal.open({
animation: $scope.animationsEnabled,
templateUrl: 'myModalContent.html',
controller: 'ModalInstanceCtrl',
size: size,
scope: $scope, // In this way
resolve: {
items: function () {
return $scope.items;
}
}
});
angular.module('ui.bootstrap.demo').controller('ModalInstanceCtrl', function ($scope, $modalInstance, items) {
$scope.items = items;
//You have available test and hello in modal
console.log("Test 1: " + $scope.test);
console.log("Test 2: " + $scope.hello);
$scope.selected = {
item: $scope.items[0]
};
$scope.ok = function () {
$modalInstance.close($scope.selected.item);
};
$scope.cancel = function () {
$modalInstance.dismiss('cancel');
};
});
Plunker of the second way

ui bootstrap modal's controller 'is not defined'

i am trying to use the modal directive from ui-bootstrap 0.6
here is the working default plunker from the ui-bootstrap page:
http://plnkr.co/edit/JGBiBSeRqOnwRhYA9py8?p=preview
now, i tried to make the coding style fits angular-seed style to include it in one app like this :
http://plnkr.co/edit/Y59rwlcNpQdijKtmjOPy?p=preview
angular.module('MyModal', ['ui.bootstrap', 'MyModal.controllers']);
angular.module('MyModal.controllers', [])
.controller('ModalDemoCtrl', [ '$scope', '$modal', '$log', function ($scope, $modal, $log) {
$scope.items = ['item1', 'item2', 'item3'];
$scope.open = function () {
var modalInstance = $modal.open({
templateUrl: 'myModalContent.html',
controller: ModalInstanceCtrl,
resolve: {
items: function () {
return $scope.items;
}
}
});
modalInstance.result.then(function (selectedItem) {
$scope.selected = selectedItem;
}, function () {
$log.info('Modal dismissed at: ' + new Date());
});
};
}])
.controller('ModalInstanceCtrl', [ '$scope', '$modalInstance', 'items', 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');
};
}]);
but it's giving an error ReferenceError: ModalInstanceCtrl is not defined
how can i make this work using this way of defining controllers ?
Provide controller name as String, exactly as you would do in route definitions, directives etc.:
var modalInstance = $modal.open({
templateUrl: 'myModalContent.html',
controller: 'ModalInstanceCtrl',
resolve: {
items: function () {
return $scope.items;
}
}
});
You can use quotes as the other answer suggests, or you can also do as the example in the docs and define the variable:
var ModalInstanceCtrl = function ($scope, $modalInstance, items) { ... }

Resources