I'm trying to implement angular UI modal and trying to set few default values before create person screen is opened. Say a new person object like below:
var person = {};
person.name = 'default';
In this function
modalCtrl.open = function(size) {
var person = {};
person.name = 'default';
console.log('person-->' + person);
console.log('person.name-->' + person.name);
var modalInstance = $modal.open({
templateUrl: 'myModalContent.html',
controller: 'ModalInstanceCtrl',
size: size,
scope: $scope,
resolve: {
person: function() {
return person;
}
}
});
I can do the same thing in update flow if the object is passed by a called.
My assumption is that I should be able to create a new object and resolve it to display few default values on create screen. Does anyone know why I can't do it? Here is the plunker:
http://plnkr.co/edit/XLrbQpDoV8bx1vktbygx?p=preview
You can resolve it.. just need to add person as a dependency to the modal instance controller
app.controller('ModalInstanceCtrl', ['$scope', '$modalInstance', 'person',
function($scope, $modalInstance, person) {
alert(person.name);
$scope.ok = function() {
$modalInstance.close($scope.person);
};
$scope.cancel = function() {
$modalInstance.dismiss('cancel');
};
}
]);
Related
I pass the link of this example, I have a variable called "greeting" that changes its value in a modal window but does not bind. Do not share scope?
http://jsfiddle.net/Bibidesign/Lodkh4jy/7/
var myApp = angular.module('myApp',['ui.bootstrap']);
myApp.controller('GreetingController', ['$scope', '$modal', function($scope,$modal) {
$scope.greeting = 'Hello!';
$scope.changeValues = function() {
var modalInstance = $modal.open({
templateUrl: 'myModalContent.html',
backdrop: 'static',
scope: $scope,
controller: function($scope, $modalInstance) {
$scope.greeting = "Welcome";
$scope.cancel = function(){
modalInstance.close();
}
$scope.ok = function(){
modalInstance.close();
}
}
});
};
}]);
You are partially there. We just need to set up passing the variables between the GreetingController and the Modal controller. We will use the resolve property on the object passed into $modal.open() to pass a value to the modal controller, and than when we close the modal, we will pass back the new value through those the results object. We are also removing scope: $scope, because the controller declaration is overriding that scope copy, and we want to keep these scopes separate. Example to follow.
This answer has a more thorough explanation of what is happening with the resolve, but it is essentially just a simplified way to resolve promises and guarantee data is in the controller before initializing the modal.
myApp.controller('GreetingController', ['$scope', '$modal', function($scope,$modal) {
$scope.greeting = 'Hello!';
// this will handle everything modal
$scope.changeValues = function() {
var modalInstance = $modal.open({
templateUrl: 'myModalContent.html',
backdrop: 'static',
// resolve is an object with all the objects we will pass to the controller
// I'm adding more than just greeting for examples sake
resolve: {
greeting: function () {
return $scope.greeting;
},
testData: function () {
return "This is some random test data";
}
}
// on the controller parameters, we add the properties we are resolving
controller: function($scope, $modalInstance, greeting, testData) {
// the greeting variable passed in through resolve
console.log('greeting', greeting); // expected output: greeting Hello!
// the testData passed in through resolve
console.log('testData', testData); // expected output: testData This is some random test data
// this will be the greeting you are able to access on the modal
// we can set this to the value from the resolve or a new value like below
$scope.greeting = "Welcome";
//$scope.greeting = greeting // this will set the modal to the value passed in from the resolve
// NOTE*** I changed this call to dismiss()
$scope.cancel = function(){
modalInstance.dismiss();
}
$scope.ok = function(){
// what ever we pass in to close will be accessible in the result below
// we are passing in the new greeting - 'Welcome'
modalInstance.close($scope.greeting);
}
}
});
// this is the majority of the new code
modalInstance.result.then(function(okReturnObject){
// this okReturnObject will be whatever you pass in to modalInstance.close()
console.log('return', okReturnObject); // expectedOutput: return Welcome
// this is where we are setting the original value to the new value from the modal
$scope.greeting = okReturnObject;
},function(){
// will be run after modalInstance.dismiss()
console.log("Modal Closed");
});
};
}]);
You can't url refer the text/ng-template as the templateUrl. Instead, add the html form in a separate html file and refer to that in the modal declaration.
Here's a working plunker https://plnkr.co/edit/lMZK0uGNsEmRjAN7teVZ?p=preview
I am trying to populate a modal form with data passed in from my controller. The data being displayed is always NULL, even though I have populated the data in the controller.
I have been trying to work this out and have tried a few different ways to do it but none work.
The examples I have seen use $scope, but I don't want to use $scope and instead use controller as
angular.module('ui.bootstrap.demo', ['ngAnimate', 'ui.bootstrap']);
(function () {
'use strict';
angular.module('ui.bootstrap.demo').controller('ModalDemoCtrl', function($uibModal, $log) {
var vm = this;
vm.vehicle = [{
vehicleRegistration: null,
createUser: null
}];
vm.open = function (size) {
vm.vehicle[0]["vehicleRegistration"] = 'ABCDEFG';
vm.vehicle[0]["createUser"] = 'BOBF';
var modalInstance = $uibModal.open({
templateUrl: 'myModalContent.html',
controller: 'ModalInstanceCtrl',
size: 'lg',
resolve: {
items: function () {
return vm.vehicle;
}
}
});
};
});
})();
(function () {
'use strict';
angular.module('ui.bootstrap.demo').controller('ModalInstanceCtrl', function ($uibModalInstance, items) {
var vm = this;
// I want to get the vehicle data pass to populate the form myModalContent.html
vm.vehicle = items;
});
})();
Any ideas?
Here is http://plnkr.co/edit/grHKGEJeKqoR8VHOW8I6?p=preview
First, use another name than vm for the modal. I've set it to vm2, also when defining the modal, you have to set the alias for the controller using the word as like this:
var modalInstance = $uibModal.open({
templateUrl: 'myModalContent.html',
controller: 'ModalInstanceCtrl as vm2',
size: 'lg',
resolve: {
items: function () {
return vm.vehicle;
}
}
});
Check the link: http://plnkr.co/edit/JmCL6NjAmd2b1UPR8649
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
});
I have a little issue by using a customize directive within the template field of UI-Bootstrap modal directive.
My aim is send data to modal via resolve attribute and re-use these resolved parameters inside the controller of my own directive.
var app = angular.module('app', ['ui.bootstrap']);
app.controller('MyCtrl', ['$scope', '$modal', function($scope, $modal) {
$scope.openModal = function () {
var popup = $modal.open({
template: '<my-modal></my-modal>',
resolve : {
mydata : function() {
return 42;
}
}
});
};
}]);
app.controller('ModalController', ['$scope', 'mydata', function($scope, mydata) {
//The error is in this directive controller
$scope.mydata = mydata;
}]);
app.directive('myModal', function() {
return {
restrict: 'E',
templateUrl : 'mymodal.html',
controller : 'ModalController',
replace: true
};
});
Maybe I proceed in the wrong way.
Any suggest to make this code functionnal ?
http://plnkr.co/edit/RND2Jju79aOFlfQGnGN8?p=preview
The resolve parameters are only injected to the controller defined in the $modal.open config parameters, but you want to inject it to the directive controller. That will not work. Imagine you would use the myModal directive somewhere else, there wouldn't be a myData object that could be used.
But i don't realy see, what you need the directive for. You could go much easier this way:
app.controller('MyCtrl', ['$scope', '$modal',
function($scope, $modal) {
$scope.openModal = function() {
var popup = $modal.open({
templateUrl: 'mymodal.html',
controller: 'ModalController',
resolve: {
mydata: function() {
return 42;
}
}
});
};
}
]);
// Here the mydata of your resolves will be injected!
app.controller('ModalController', ['$scope', 'mydata',
function($scope, mydata) {
$scope.mydata = mydata
}
]);
Plunker: http://plnkr.co/edit/bIhiwRjkUFb4oUy9Wn8w?p=preview
you need to provide an Object "mydata". Ensure, that you have a correct implemented factory which provides your myData Object. If you had done that, you can "inject" your myData Object where ever you want to.
yourApp.MyDataFactory = function () {
var myData = {i: "am", an: "object"};
return myData;
}
this would provide an "myData" Object
I'm not sure what you are trying to accomplish with the directive, but if you are trying to provide a generic way to invoke the $model, that you can then use from many places in your app, you may be better off to wrap $model with a service. Than you can then call from other places in your app.
I forked and modified your plunkr to work this way: http://plnkr.co/edit/0CShbYNNWNC9SiuLDVw3?p=preview
app.controller('MyCtrl', ['$scope', 'modalSvc', function($scope, modalSvc) {
var mydata = {
value1: 42
};
$scope.openModal = function () {
modalSvc.open(mydata);
};
}]);
app.factory('modalSvc', ['$modal', function ($modal) {
var open = function (mydata) {
var modalInstance,
modalConfig = {
controller: 'ModalController',
resolve: {
mydata: function () {
return mydata;
}
},
templateUrl: 'mymodal.html'
};
modalInstance = $modal.open(modalConfig);
return modalInstance;
};
return {
open: open
};
}]);
Also, I changed mydata to be an object, rather than '42', as I am sure you will have other data to pass in. the markup was updated accouringly:
<div class="modal-body">
BODY {{mydata.value1}}
</div>
Doing it this way, the resolve property works, and you can get your data.
As for the other answers mentioning you must define mydata, the resolve property passed into $model does this for you, so it can be injected into the modal's controller (ModalController), like you have done.
I have a completely working version of the ui.bootstrap.modal as per the example here http://angular-ui.github.io/bootstrap/#/modal but I want to take a stage further and add it to my controller configuration.
Perhaps I'm taking it too far (or doing it wrong) but I'm not a fan of just
var ModalInstanceCtrl = function ($scope...
My modal open controller:
var controllers = angular.module('myapp.controllers', []);
controllers.controller('ModalDemoCtrl', ['$scope', '$modal', '$log',
function($scope, $modal, $log) {
$scope.client = {};
$scope.open = function(size) {
var modalInstance = $modal.open({
templateUrl: 'templates/modals/create.html',
controller: ModalInstanceCtrl,
backdrop: 'static',
size: size,
resolve: {
client: function () {
return $scope.client;
}
}
});
modalInstance.result.then(function (selectedItem) {
$log.info('Save changes at: ' + new Date());
}, function () {
$log.info('Closed at: ' + new Date());
});
};
}
]);
Modal instance controller:
var ModalInstanceCtrl = function ($scope, $modalInstance, client) {
$scope.client = client;
$scope.save = function () {
$modalInstance.close(client);
};
$scope.cancel = function () {
$modalInstance.dismiss('cancel');
};
};
However I would like to change this last controller to:
controllers.controller('ModalInstanceCtrl', ['$scope', '$modalInstance', 'client',
function ($scope, $modalInstance, client) {
$scope.client = client;
$scope.save = function () {
$modalInstance.close(client);
};
$scope.cancel = function () {
$modalInstance.dismiss('cancel');
};
}
]);
If I also update the controller reference within $scope.open for ModalDemoCtrl controller to
controller: controllers.ModalInstanceCtrl
then there are no errors but the save and cancel buttons within the modal window no longer work.
Could someone point out where I am going wrong - possibly a fundamental lack of understanding of the way controllers work within the AngularJS?!
Controller specified in $scope.open needed single quotes around it.
controller: 'ModalInstanceCtrl',
You are referencing your module to variable controllers.
All controllers in angular systems has unique names.
The controller is still "ModalInstanceCtrl" not "controllers.ModalInstanceCtrl".