passing objects to modal dialog in AngularJS/bootstrap - javascript

I'm trying to pass an object into a modal dialog in a bootstrap/angularJS using the code below. I did this in the style of the answer given at AngularJS UI Bootstrap modal is unable to perform functions from scope. When the modal form is supposed to open from a call to editGroup(), I get the following error:
Error: [$injector:unpr] Unknown provider: selGroupProvider <- selGroup
var EditGroupModalController = function ($scope, $modalInstance, selGroup) {
$scope.user = $sessionStorage.user;
$scope.selGroup = selGroup;
$scope.closeModal = function () {
$modalInstance.close();
};
};
$scope.editGroup = function (selGroup) { // "selGroup" receives the current Group object from $scope.groupList[]
$modal.open({
templateUrl: 'app/views/administration/advanced/editgroup.html',
controller: ['$scope', '$modalInstance','$modal','$sessionStorage','advancedService','selGroup', EditGroupModalController],
size: 'lg',
windowTemplateUrl:'app/views/partials/modaltemplatedraggable.html',
backdrop:'static',
resolve: {
item: function () {
return selGroup;
}
}
});
};
The official description of this error is here; however, I do not understand why I am receiving this error. Any help with this would be greatly appreciated.

Your controller's dependencies list doesn't match controller's function definition: in $modal.open you've listed six dependencies, while in function only three are present.
Dependencies are injected by resolve keys - in your case the key is item.
Necessary changes to your code in order to make it work:
Replace (1)
var EditGroupModalController = function ($scope, $modalInstance, selGroup)
with
var EditGroupModalController = function ($scope, $modalInstance, $modal, $sessionStorage, advancedService, selGroup)
And replace (2)
resolve: {
item: function () {
With
resolve: {
selGroup: function () {

You should name the variable in the resolve as 'selGroup' instead of 'item' so that it can be correctly injected.
Also, the names of the declared dependencies should match the function definition. I put together this simple demo.
angular.module('test', ['ui.bootstrap']).controller('TestController', function($scope, $modal) {
var sel = {name: "A group"};
var EditGroupModalController = function($scope, $modalInstance, selGroup) {
$scope.selGroup = selGroup;
$scope.closeModal = function() {
$modalInstance.close();
};
};
$scope.editGroup = function(selGroup) { // "selGroup" receives the current Group object from $scope.groupList[]
$modal.open({
template: '<div>Test {{selGroup.name}}</div>',
controller: ['$scope', '$modalInstance', 'selGroup', EditGroupModalController],
size: 'lg',
backdrop: 'static',
resolve: {
selGroup: function() {
return sel;
}
}
});
};
});
http://plnkr.co/edit/ec1PjkDZtf4yqINONnX5?p=preview

Related

$scope is getting lost while opening a modal on ng-click

When I am trying to open a modal on ng-click the scipe variables is getting lost.
var modalInstance = $modal.open({
templateUrl: 'partials/create.html',
controller: 'AppCreateCtrl',
scope: $scope // <-- I added this
});
You should pass data using the resolve property like this:
var modalInstance = $modal.open({
templateUrl: templateSrv.templateUrl('partials/create.html'),
controller: modalBootstrap,
backdrop: 'static',
keyboard: false,
resolve: {
data: function () {
var result = {};
result.scope = $scope;
return result;
}
}
});
modalInstance.result.then(
function (dataPassedFromModalConroller) {
//this is called when the modal is closed
},
function (dataPassedFromModalConroller) { //Dismiss
//this is called when the modal is dismissed
}
);
Specify the controller for the modal instance like this (we do this in another file):
var modalBootstrap= function ($scope, $modalInstance, data) {
$scope.modalInstance = $modalInstance;
$scope.scope = data.userId;
};
modalBootstrap['$inject'] = ['$scope', '$modalInstance', 'data'];
Your modal template would look something like this:
<div ng-controller="AppCreateCtrl">modal content here</div>

AnguarJS Modal ID is not defined

I'm trying to implement an AngularJS Modal.
This is my call for the modal
<button data-ng-disabled="!caixa.ativo" data-ng-click="abrir(caixa.id)" class="btn btn-primary btn-xs">Alterar</button>
This is my function
$scope.abrir = function(caixaId) {
var modalInstance = $modal.open({
templateUrl: 'add_modal',
controller: $scope.model,
resolve: {
id: function() {
return caixaId;
}
}
});
};
$scope.model = function($scope, $modalInstance) {
$scope.alerts = [];
//if I remove this code, the modal opens correctly
if (angular.isDefined(id))
alert('edit');
};
But when I click the button, I get this error
Error: id is not defined
$scope.model#http://localhost:8080/websys/resources/js/CaixaController.js:38:1
invoke#http://ajax.googleapis.com/ajax/libs/angularjs/1.3.8/angular.js:4182:14
instantiate#http://ajax.googleapis.com/ajax/libs/angularjs/1.3.8/angular.js:4190:27
$ControllerProvider/this.$get</<#http://ajax.googleapis.com/ajax/libs/angularjs/1.3.8/angular.js:8449:18
resolveSuccess#http://angular-ui.github.io/bootstrap/ui-bootstrap-tpls-0.10.0.js:1710:32
processQueue#http://ajax.googleapis.com/ajax/libs/angularjs/1.3.8/angular.js:13170:27
scheduleProcessQueue/<#http://ajax.googleapis.com/ajax/libs/angularjs/1.3.8/angular.js:13186:27
$RootScopeProvider/this.$get</Scope.prototype.$eval#http://ajax.googleapis.com/ajax/libs/angularjs/1.3.8/angular.js:14383:16
$RootScopeProvider/this.$get</Scope.prototype.$digest#http://ajax.googleapis.com/ajax/libs/angularjs/1.3.8/angular.js:14199:15
$RootScopeProvider/this.$get</Scope.prototype.$apply#http://ajax.googleapis.com/ajax/libs/angularjs/1.3.8/angular.js:14488:13
ngEventHandler/<#http://ajax.googleapis.com/ajax/libs/angularjs/1.3.8/angular.js:22954:17
m.event.dispatch#http://code.jquery.com/jquery-latest.min.js:3:8384
m.event.add/r.handle#http://code.jquery.com/jquery-latest.min.js:3:5122
The reason your ID is not defined is you are not injecting id as a dependency to your controller.
$scope.abrir = function(caixaId) {
var modalInstance = $modal.open({
templateUrl: 'add_modal',
controller: modalController,
resolve: {
// adding id as a property here allows you to inject it
// into the controller defined below
id: function() {
return caixaId;
}
}
});
};
// you don't need to bind this controller to your scope
// you don't need to inject $modalInstance as a dependency here,
// but you do need to inject id
function modalController($scope, id) {
$scope.alerts = [];
// now id should be defined since you added it as a dependency
if (angular.isDefined(id))
alert('edit');
};

What's the most common reason for ModalInstanceCtrl to give this error?

I am trying to hook up an Angular Bootstrap modal (pop-up) but it's giving me either "templateUrl" not found error, or this error: Error: [ng:areq] http://errors.angularjs.org/1.3.15/ng/areq?p0=ModalInstanceCtrl&p1=not%20a%20function%2C%20got%20undefined
I just want some theoretical suggestions on why that would be the case. I have tried a lot of things: it's all properly hooked up, all the spelling matches, etc, etc.
$modal is being used in the controller with other functions as well, so it's all being injected.
Angular Documents provide a suggestion that when you get this error it is possible that you have a controller being injected into another controller. Which is exactly what was happening with my attempt to add a modal as their box solution:
angular.module('ui.bootstrap.demo').controller('ModalDemoCtrl', function ($scope, $modal, $log) {
$scope.items = ['item1', 'item2', 'item3'];
$scope.animationsEnabled = true;
$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.result.then(function (selectedItem) {
$scope.selected = selectedItem;
}, function () {
$log.info('Modal dismissed at: ' + new Date());
});
};
$scope.toggleAnimation = function () {
$scope.animationsEnabled = !$scope.animationsEnabled;
};
});
controller: 'ModalInstanceCtrl' MUST BE removed from your modal function if you're adding it to an existing controller, otherwise it will all go to ... you know where.
Can be as simple as the controller not existing on your module.
I forgot to add the code for the modal controller :( when I first tried it in my project
This controller is about 3 controllers deep in my project (make sure your using "controller AS cntlr" style) so embedding wasn't a problem for me.
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');
};
});

pass simple parameter to angular ui-bootstrap modal?

I see many posts about posting many complicated things to ui-bootstrap modals, but I just want to pass a simple parameter so that I might use it to display different content in the dialog.
For example, I have the main document which has MyDocumentController as mydoc
In MyDocumentController is a function such as
_this.modals = {
inviteUser: function() {
$modal.open({
animation: true,
templateUrl: 'modules/templates/modals/modal-invite-user.html',
controller: 'UserInviteModalController as invite',
size: 'lg'
});
}, ...
And I call it in the main document like so, here is where I want to pass the param from:
<a href="" ng-click="users.modals.inviteUser(returningUser)">
And here is the controller for the modal:
(function() {
'use strict';
angular.module('mymodule')
.controller('UserInviteModalController', function($log, $modalInstance, toastr) {
var _this = this;
_this.someVar = HERE'S WHERE I WANT TO GET THE VALUE returningUser FROM THE NG-CLICK
_this.inviteDialog = {
close: function() {
$modalInstance.close();
},
resendInvite: function() {
toastr.success('A new invite has been sent.');
$modalInstance.close();
}
};
});
})();
What is the process for passing the simple param to the dialog's controller?
Try using resolve:
_this.modals = {
inviteUser: function(returningUser) {
$modal.open({
animation: true,
templateUrl: 'modules/templates/modals/modal-invite-user.html',
controller: 'UserInviteModalController as invite',
size: 'lg',
resolve: {
returningUser: function() {
return returningUser;
}
}
});
}, ...
And then inject it into your controller:
angular.module('mymodule')
.controller('UserInviteModalController', function($log, $modalInstance, toastr, returningUser) {
var _this = this;
_this.someVar = returningUser;

How to declare an angular-bootstrap modal in a way that is safe for minimization

I have implemented an angular modal dialog box following the guidelines given at: http://angular-ui.github.io/bootstrap/. The code below works fine when the non-minified files are accessed, but it fails when minification is applied. I have narrowed the problem down to the declaration of the modalInstanceCtrl function below, however I am not clear on how I can implement this function in a minification-friendly manner. I have tried to declare the modalInstanceCtrl function using standard controller syntax, but in that case, the function is not found by the $modal.open call.
The error message that I receive from the minified code is "TypeError: Cannot read property 'value' of undefined".
What is the best way to declare this controller so that it can be both minified as well as called from the $modal.open function?
Any help would be greatly appreciated.
lxModalSupportServices.factory('lxModalSupportService',
function ($modal, $log, $timeout) {
var modalInstanceCtrl = function($scope, $log, $modalInstance) {
$scope.ok = function () {
$modalInstance.close();
};
};
return {
showCameraAndMicrophoneModalWindow : function(scope, htmlTemplate) {
var ModalInstance = $modal.open({
templateUrl: htmlTemplate,
controller: modalInstanceCtrl
});
....
}
});
Change the declaration to
var ModalInstanceCtrl = [
'$scope', '$log', '$modalInstance',
function($scope, $log, $modalInstance) {
$scope.ok = function () {
$modalInstance.close();
};
}
];
and try again. If it still fails, probably the problem is somewhere else.
Normally I would declare the controller for $modal separately:
lxModalSupportServices.controller('AddCommentModalCtrl', ['$scope', function($scope) {
'use strict';
// Implementation...
});
Then use it with string
$modal.open({
templateUrl: htmlTemplate,
controller: 'AddCommentModalCtrl',
});

Categories