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;
Related
Well, so I have seen a lot of people struggling to close the angular-strap modal from controller. I got some of the answers, but actually they do it differently (I do not want to change the code style). I open modal using my modalFactory, and so I do not have modalInstance with me. So I am compeltely not sure, how I can close this.
With angular-bootstrap, I know I can inject uibModalInstance and call uibModalInstance.dismiss() to close the function. But how I can do similar with the angular-strap modal.
Here is my factory:
(function (app) {
'use strict'
app.factory('modalFactory', ['$modal', function ($modal) {
var local = this;
local.modalInstance = ['$scope',
function ($scope) {
$scope.myVar = "Some variable input ";
$scope.closeModal = function(){
console.log("CLose function has been called..")
// How I can close this.
}
}];
return {
openMyModal: function (ip) {
$modal({
templateUrl: 'myModal.html',
controller: local.modalInstance,
size: 'lg',
resolve: {
ip: function () {
return ip;
}
}
})
}
}
}])
})(app);
Complete plunkr is available here.
Call $scope.$hide() inside you clodeModal method.
(function (app) {
'use strict'
app.factory('modalFactory', ['$modal', function ($modal) {
var local = this;
local.modalInstance = ['$scope',
function ($scope) {
$scope.myVar = "Some variable input ";
$scope.closeModal = function(){
console.log("CLose function has been called..")
$scope.$hide();
}
}];
return {
openMyModal: function (ip) {
$modal({
templateUrl: 'myModal.html',
controller: local.modalInstance,
size: 'lg',
resolve: {
ip: function () {
return ip;
}
}
})
}
}
}])
})(app);
Update plunker: http://plnkr.co/edit/2FxoBzY0vQqdrxqptm6F?p=preview
I want to use same modal window with different parent controller, the only difference in modal controller is separate factories that i am calling e.g Ctrl-1-Factory.getServerFiles so similarly i want to call Ctrl-2-Factory when modal populated for Ctrl2.
ModalCtrl.js
angular.module('App').controller('ServerFilesCtrl', function($scope, $rootScope, FileSaver, $uibModalInstance, Ctrl-1-Factory, $uibModal) {
'use strict';
$scope.cancel = function() {
$uibModalInstance.close();
}
Ctrl-1-Factory.getServerFiles().then(function(response) {
$scope.data = response.data;
console.log($scope.data);
});
});
Ctrl-1.js
$scope.modalInstance = $uibModal.open({
templateUrl: '/web/global/modal.html',
controller:'ModalController'
});
Ctrl-2.js
$scope.modalInstance = $uibModal.open({
templateUrl: '/web/global/modal.html',
controller:'ModalController'
});
You can wrap it in a service method.
angular.module('App').factory('FilesModal', function() {
return {
openModal: openModal
};
function openModal() {
return $uibModal.open({
templateUrl: '/web/global/modal.html',
controller: 'ModalController'
});
}
});
angular.module('App').controller('Ctrl1', function(FilesModal) {
$scope.someEventFunction = someEventFunction;
function someEventFunction() {
$scope.modalInstance = FilesModal.openModal();
}
});
Pass in arguments as needed to make it more robust
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');
};
});
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
I have two states, one is a child of the other. One represents a list of people (people) and one for when you click on an individual person to view more details (people.detail).
My first state works as intended, and has several parameters which represent all the various server side filters and paging you could apply. The child state is a modal window, which popups as expected but my only paramater personID never makes it into $stateParams. I wonder if it's something to do the combination of the RESTful style URL and the query string style?
It is perhaps worth noting that $stateParams is populated with everything you'd expect from the parent state.
EDIT: Plunker to show what I mean - http://plnkr.co/edit/eNMIEt?p=info (note that the ID is undefined)
app.js
$urlRouterProvider.otherwise('/people');
$stateProvider
.state('people', {
url: '/people?pageNumber&pageSize&sortField&sortDirection&search&countryID&jobFunctionIDs&firmTypeIDs',
templateUrl: 'Static/js/angular/views/people-list.html',
controller: 'PeopleListController',
resolve: {
api: "api",
people: function (api, $stateParams) {
//Code ommitted
},
countries: function (api) {
//Code ommitted
},
jobFunctions: function (api) {
//Code ommitted
},
firmTypes: function (api) {
//Code ommitted
}
}
});
modalStateProvider.state('people.detail', {
url: "/{personID}",
templateUrl: 'Static/js/angular/views/people-detail.html',
controller: function () {
},
resolve: {
person: function (api, $stateParams) {
return api.people.getDetail($stateParams.personID);
}
}
});
The modalStateProvider looks like:
angular.module('myApp')
.provider('modalState', function ($stateProvider) {
var provider = this;
this.$get = function () {
return provider;
}
this.state = function (stateName, options) {
var modalInstance;
$stateProvider.state(stateName, {
url: options.url,
onEnter: function ($modal, $state) {
modalInstance = $modal.open(options);
modalInstance.result['finally'](function () {
modalInstance = null;
if ($state.$current.name === stateName) {
$state.go('^');
}
});
},
onExit: function () {
if (modalInstance) {
modalInstance.close();
}
}
});
};
})
And finally my function in my controller to transition to the people.detail state:
$scope.transitionToPersonDetail = function (personID) {
$state.transitionTo('.detail', { personID: personID }, { location: true, inherit: true, relative: $state.$current, notify: false });
};
After a lot more inspection I'm still not entirely sure why this was happening, I think it had something to do with the modalStateProvider's scope with $stateParams and the fact that the state wasn't "ready". All of this is purely speculation however.
I fixed it with this code:
$stateProvider.state('people.detail', {
url: '/{personID:int}',
onEnter: ['$stateParams', '$state', '$modal', 'api', function($stateParams, $state, $modal, api) {
$modal.open({
templateUrl: 'Static/js/angular/views/people-detail.html',
controller: function(person) {
console.log(person);
},
resolve: {
person: function() {
return api.people.getDetail($stateParams.personID);
}
}
}).result['finally'](function(result) {
$state.transitionTo('people');
});
}]
});
As far as I remember the value from 'resolve' is directly available in controller, although I think it's worth checking if controller for your child view is triggered at all
modalStateProvider.state('people.detail', {
url: "/:personID",
templateUrl: 'Static/js/angular/views/people-detail.html',
controller: function () {
console.log(person)
},
resolve: {
person: function (api, $stateParams) {
return api.people.getDetail($stateParams.personID);
}
}
});