How to pass a function to angular ui bootstrap modal - angularjs

What is the best way to pass a function to an angular ui bootstrap modal dialog? I created a method in my modal controller that calls $scope.$parent.myMethod() like so:
$scope.isChosen = function(concept) {
return $scope.$parent.isChosen(concept);
};
This works, but I would rather pass the function to the modal in a similar way to how functions are passed to directives. I've tried to use the modal "resolve" parameter to do this but without success. Is it possible to resolve a function for a modal, and if so, what is the syntax? If not possible, is there any other way to do this other than accessing the parent scope?
Edit: Here is a plunk attempting to pass a method to a modal, it is a little simplified but represents what I'm trying to do: http://plnkr.co/edit/eCjbZP

When you are defining your modal , you must resolve like this :
// here is the controller where you want to trigger the modal to open
$scope.openModal = function () {
// somewhere in your html , you may click on a button to envoke openModal()
var modalInstance = $modal.open({
templateUrl: 'myModalContent.html',
controller: ModalInstanceCtrl,
size: size,
resolve: {
isChosen: function () {
return $scope.isChosen;
}
}
});
};
And later on , in your modalCtr you can inject isChosen like this :
app.controller('modalCtrl',function($scope,isChosen){
// now you can use your isChosen function however you want
});

Related

Angularjs dialog call another controller function on close

AngularJs:
I'm trying to show an edit modal box. For this, I'm using $mdDialog of AngularJs material design. Here is my code:
angular.module('main').controller('UserCtrl', ['$scope', function($scope){
function loadUser(){
...
}
function showEditSale(index) {
var sale = $scope.user.Sales[index];
$mdDialog.show({
clickOutsideToClose: true,
fullscreen: $scope.customFullscreen,
parent: angular.element(document.body),
locals: {
sale: sale
},
templateUrl: 'front/templates/user/edit-sale.html',
controller: 'UserSaleCtrl'
})
.then(function(answer) {
}, function() {
});
}
}]);
angular.module('main').controller('UserSaleCtrl', ['$scope', function($scope, sale){
$scope.sale = sale;
function updateSale(){
...
**Need to reload user**
}
}]);
When I click on edit button against user sale, I call showEditSale passing the index of user.Sales item. A popup is displayed and I can edit values there. When clicking on update, an api is called which is updating sale information.
The problem is I want to reload this user. To reload, I have to call function from another controller.
My questions are:
Is there another way to pass data to dialog box instead of injecting in controller?
Do I have to use emit event of AngularJs to call function of another controller?
Can I somehow use same controller? I tried but I think $scope is being reset for modal dialog.
I added following code in UserSaleCtrl:
function updateSale(){
...
$rootScope.$broadcast('reloadUser');
}
Added following code in UserCtrl:
$scope.$on('reloadUser', function(event) {
loadUser();
});

angular md-dialog using controller scope

I open a dialog with mdDialog when checking a checkbox (in the example checkbox 1).
Within this dialog there are several input fields, which should be connected via ng-modell to a controller - but it seems, that is not the scope used by the main controller (in the example myCtrl).
How can I use the same scope in the dialog and myCtrl? I tried locals to access the parent scope, but this didn't work.
Here is the plunker:
[https://plnkr.co/edit/9biRK5oskpQRhRWyeHWd](https://plnkr.co/edit/9biRK5oskpQRhRWyeHWd)
just pass the $scope to $mdDialog.show
$mdDialog.show({
scope: $scope,
controller: function () {
// ...
}
});
Remove the loacals. It can use myCtrls scope.
<md-radio-group ng-model="dialog_radio1">
Then in the cancel function I was able to log the selected radio value from myCtrls' scope.
$scope.cancel = function () {
$mdDialog.cancel();
console.log($scope.dialog_radio1);
};

Create several similar Angular dialogs without lots of code and templates

I'm using the modal module of Angular UI to create dialog boxes. I need to create several boxes which are quite similar. They look roughly like this:
Question?
yes (yellow button), no, cancel
Question?
yes (yellow button), no
cancel
option 1
option 2 (yellow button)
option 3
Is there a smart way I can avoid having to create HTML templates for each individual dialog? In other languages I would do something like "result = showDialog("Question?", ["ok", "cancel"])". I want to avoid putting things in my controller that should really not be there though (e.g. presentation stuff).
By the way, I don't get to decide how the UI looks by the way so they must look like this...
You can create a single template and a single controller that would handle all of these scenarios, just applying different options through the controller:
var ModalInstanceCtrl = function ($scope, $modalInstance, options) {
$scope.options = options;
$scope.yes = function () {
$modalInstance.close('yes');
};
$scope.no = function () {
$modalInstance.dismiss('no');
};
$scope.cancel = function () {
$modalInstance.dismiss('cancel');
};
};
Then wrap the call to that modal inside a function that can be called wherever you need it:
$scope.showDialog = function (question, title, showCancel) {
var modalInstance = $modal.open({
templateUrl: 'myModalContent.html',
controller: ModalInstanceCtrl,
resolve: {
options: function () {
return {
question: question,
title: title,
showCancel: showCancel
};
}
}
});
modalInstance.result.then(function (action) {
$scope.selected = action;
}, function (action) {
$scope.selected = action;
});
};
Then a modal template that displays whatever you need based on the options passed in. Here's a plunker demonstrating the idea: http://plnkr.co/edit/y3c5bz5AXjrNo1XFzMBP
Of course, if you are going to use such a thing throughout your application, it would be wise to abstract it out into a service, rather than have it be a function attached to $scope.
Within a single html template, create multiple buttons, and in conjunction with custom options, show or hide the buttons using ng-show. Example: ng-show="showButton3".

AngularUI Bootstrap Modal. Scope issue

Im fairly new to AngularJS and I'm trying to create an List with "Draggables" that you can drop in 4 lists which are sortable. I got this to work with AngularUI-Sortable.
Now for the next part I'm trying to edit the content (more options and settings in the feature). With a modal from AngularUI-Bootstrap.
I got this to work with opening the content from the selected item I want to edit.
As you can see in the Plunker I almost got it working. Only thing I cant figure out is how I can get the {{ item }} to be {{ widgetOption }} AFTER I pressed the save button.
http://embed.plnkr.co/TTNccRuToObZuSmwYlTG/preview
My approach would be to keep a reference to the original object in your modal controller. So, assume the object passed in is the original, and it should only be modified if the form is saved. Making the fewest changes possible to your code to make it work, I came up with this plunker.
http://plnkr.co/edit/eSbEZZajsNfmVv3vmTdc?p=info
var modalInstance = $modal.open({
templateUrl: 'modal.html',
controller: ModalInstanceCtrl,
resolve: {
widgetOptionsLocal: function () {
return widgetOptions;
}
}
});
var ModalInstanceCtrl = function ($scope, $modalInstance, widgetOptionsLocal) {
var widgetOptionsOriginal = widgetOptionsLocal;
$scope.widgetOptions = angular.copy(widgetOptionsLocal);
$scope.ok = function () {
widgetOptionsOriginal.content = $scope.widgetOptions.content;
$modalInstance.close($scope.widgetOptions);
};
$scope.cancel = function () {
$modalInstance.dismiss('cancel');
};
};

Can I change a directive's controller for different instances of the directive?

I have created a directive called modalDialog, which is basically that, a modal dialog. It uses transclude, so I can later do this in my code:
<div modal-dialog id="dialog" dialog-title="This is my Dialog">
...
here goes the content of the dialog
</div>
I want to use this directive in different places of my application, and for different purposes. The content of the dialogs will vary, naturally, so it would be very nice to have a way to pass the Controller to the directive, in the same way that I pass the dialog-title or any other parameter.
I thought about wrapping the modal-dialog in a div, with a controller set on it. Like this:
<div ng-controller="ThisInstanceController">
<div modal-dialog id="dialog" dialog-title="This is my Dialog">
...
here goes the content of the dialog
</div>
</div>
But I don't quite like it. Is there a more elegant way to do it?
Take a look at Angular-UI modals. They have a pretty elegant way of using modals. In short you can pass which controller you'd like to initialize when the modal opens.
$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('Modal dismissed at: ' + new Date());
});
};
The nice part as well is you can pass data with the resolve between controllers.

Resources