$mdDialog not close - angularjs

I am having mdDialog in one controller to show details from another controller.when I click the close button, it does not close.
I used both :
$mdDialog.hide() and $mdDialog.cancel()

re-check all these:
correct usage of $mdDialog API:
$mdDialo.show({
controller:function($scope,$mdDialog){
$scope.close = function(){$mdDialog.hide();}
},
templateUrl:'some-template.dialog.html'
})
correct link from controller to template.
i.e. if you are using $scope.close = function(){ ... }, then your template should look like : <md-button ng-click=close()>close</md-button>
and if you are using controller:
this.close = function(){...}
then you need to add a controllerAs in your $mdDialog.show() config object:
controllerAs:'$ctrl'
and in your template:
<md-button ng-click=$ctrl.close()></md-button>

Related

$uibModal templateUrl does not change modal content

all!
I'm making an angular application and want to implement a simple modal window popup, that will allow users to "construct" a URL.
My page looks like this:
Here's the HTML of the URL button (third in row) that is to trigger my button.
<button class="btn btn-secondary" ng-click="vm.showUrlModal()" id="button-url-to-modal" type="button" title="Hyperlink <a> Ctrl+L"><img src="/images/url.png" height="18px"/></button>
The controller that handles the page looks like this:
(function() {
function postchallengeController($uibModal, newChallengeData) {
var vm = this;
vm.message = "Post a challenge!";
vm.showUrlModal = function() {
$uibModal.open({
templateUrl: '/url_modal/url_modal.view.html',
controller: 'url_modal',
controllerAs: 'vm',
})
}
postchallengeController.$inject = ['$uibModal', 'newChallengeData'];
/* global angular */
angular
.module('stackunderflow')
.controller('postchallengeController', postchallengeController);
})();
And the referenced url_modal controller:
(function() {
function url_modal($uibModalInstance) {
var vm = this;
vm.modal = {
cancel: function() {
$uibModalInstance.close();
}
};
}
url_modal.$inject = ['$uibModalInstance'];
/* global angular */
angular
.module('stackunderflow')
.controller('url_modal', url_modal);
})();
In the referenced document (/url_modal/url_modal.view.html) is a simple Hello World, that should be displayed when I open the modal - however, when I do so, the page opens a modal with the current content overlayed on top of it.
See here :
What could I be doing wrong?
Thank you!
EDIT: I do have both controllers referenced in my index.html and my module does contain ['ui.bootstrap']
The error might be hidden in the reference of the html file.
Make sure that the parent directory of the /url_modal/ directory is set as the root folder you set with express.static function call.

Angular JS material dialog with multiple options to save

I'm trying to have a dialog with multiple options to save and another option to save and close as well as cancel option, where the (save and close) button will save the data and close the dialog, while the (save) button will save the data in modal then open an empty instance of the modal, the problem is when adding two options with save I see only buttons for save and cancel, here is the angular Material Snippet example I'm modifying:
$scope.showConfirm = function(ev) {
// Appending dialog to document.body to cover sidenav in docs app
var confirm = $mdDialog.confirm()
.title('Would you like to delete your debt?')
.textContent('All of the banks have agreed to forgive you your debts.')
.ariaLabel('Lucky day')
.targetEvent(ev)
.ok('Save and Close')
.ok('Save')
.cancel('Cancel');
When clicking on Confirm Dialog button I would like to see three buttons, below is the modified code:
https://codepen.io/anon/pen/dgWzjw
You can't achieve the dialog presentation you've described using $mdDialog.confirm().
This method provides a preconfigured dialog that can only ever have two action buttons. You can build the dialog you want by providing more configuration parameters to $mdDialog.show().
Here's an example.
You'll need to provide the HTML for your custom dialog:
<script type="text/ng-template" id="custom-confirm.html">
<md-dialog>
<md-dialog-content>
<md-content layout-padding>
<div>...</div>
</md-content>
</md-dialog-content>
<md-dialog-actions>
<md-button ng-click="cancel()">Cancel</md-button>
<md-button ng-click="save()">Save</md-button>
<md-button ng-click="saveAndClose()">Save and Close</md-button>
</md-dialog-actions>
</md-dialog>
</script>
Then provide a custom dialog configuration to $mdDialog.show():
$scope.showCustomConfirm = function () {
$mdDialog.show({
controller: function ($scope, $mdDialog) {
$scope.cancel = function () {
$mdDialog.cancel();
};
$scope.save = function () {
/* ... */
};
$scope.saveAndClose = function () {
/* ... */
};
},
templateUrl: 'custom-confirm.html',
});
};
I've forked your CodePen to include the example described above.
Edit
To have the save button reopen the same dialog, simply chain the the call to open the dialog onto a call to first hide it. You can do this because the return value of $mdDialog.hide() is a promise that resolves once the dialog has hidden itself.
To follow on from the above example, you'll need to do some some slight refactoring to make sure you're not shadowing $scope:
$scope.showCustomConfirm = showCustomConfirm;
function showCustomConfirm() {
$mdDialog.show({
controller: function ($scope, $mdDialog) {
$scope.save = function () {
// Save data...
$mdDialog.hide().then(showCustomConfirm);
};
// Everything else as before...
},
});
}
And here's an updated CodePen fork.

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();
});

Ionic v1 global $ionicPopover menu

for my ionic v1 app I need to add one header menu (like as bootstrap menu) in right corner. When I click this button, i need to show menu with same ng-click event. For graphical requirement I need a menu and no side menu.
Found $ionicPopover, and I think that is my solution.
My problem is about menu function. My idea is use a html template for all menu, and put popover function samewhere accessibile for all my app. Is possibile?
Found only example where for every controller I need to implement popover function.
For example this is a simple controller. I need to define popover function globally for all my project. Same for popover definition. Is possible? Thanks.
.controller('DashCtrl', function($scope, $ionicLoading, $ionicPopover) {
// .fromTemplate() method
var template = '<ion-popover-view>' + '<ion-header-bar>' +
'<h1 class = "title">Popover Title</h1>' +
'</ion-header-bar>'+ '<ion-content>' +
'Popover Content!' + '</ion-content>' + '</ion-popover-view>';
$scope.popover = $ionicPopover.fromTemplate(template, {
scope: $scope
});
$scope.openPopover = function($event) {
$scope.popover.show($event);
};
$scope.closePopover = function() {
$scope.popover.hide();
};
//Cleanup the popover when we're done with it!
$scope.$on('$destroy', function() {
$scope.popover.remove();
});
// Execute action on hide popover
$scope.$on('popover.hidden', function() {
// Execute action
});
// Execute action on remove popover
$scope.$on('popover.removed', function() {
// Execute action
});
})
Like stated in my comment, you should create a root-template view with a separate Controller that holds the logic shared by all views. Take the following setup as an example:
The "Root Template": (Contains the Menu Button)
<!-- templates/root.html -->
<div>
<ion-nav-bar class="bar-positive">
<ion-nav-buttons side="right">
<button class="button icon ion-android-more-vertical" ng-click="showMenu($event)"></button>
</ion-nav-buttons>
</ion-nav-bar>
<ion-nav-view name="content"></ion-nav-view>
</div>
Dash Templates:
<!-- views/dash.html -->
<ion-view view-title="Dash View">
<ion-content>
Hello World!
</ion-content>
</ion-view>
The states:
$stateProvider
.state('root', {
url: '/root',
abstract: true,
templateUrl: 'templates/root.html',
controller: 'RootCtrl'
})
.state('root.dash', {
url: '/sub',
views: {
'content': {
controller: 'DashCtrl',
templateUrl: 'views/dash.html'
}
}
})
In the DashCtrl you will put your logic to handdle the popup. Thus this controller has to implement the showMenu($event) function.
If you really need a template for your popover, you can define the template in either in the html of templates/root.html or in the code of **RootController.js".
Finally, I create single function in single controller, with a common menu header. Thanks.
I know the OP resolved his issue but did it in a different way than was originally asked. The OQ was how to do a global popover...the accepted answer was to do controller view instead.
But to do a global popover, this is how I did it. I am certain some might object to this because of the dependency of $rootScope but it is a working solution:
In app.js:
var popoverPromise = $ionicPopover.fromTemplateUrl('templates/windowPopup.html', {
scope: $rootScope,
focusFirstInput:false
});
popoverPromise.then(function(popover) {
$rootScope.msgPopover = popover;
});
$rootScope.globalPopover = function(tpt,tps,tpm,tps1,tpm1,tpa,tpc) {
popoverPromise.then(function(popover) {
$rootScope.popInfo.title = tpt ;
$rootScope.popInfo.sub = tps ;
$rootScope.popInfo.msg = tpm ;
$rootScope.popInfo.sub1 = tps1;
$rootScope.popInfo.msg1 = tpm1 ;
$rootScope.popInfo.action = tpa ;
$rootScope.popInfo.color1 = tpc ;
$popover.show();
}) ;
}
$rootScope.globalClosePopover = function() {
$rootScope.msgPopover.hide();
}
And then from all the various controllers where you need it, inject $rootScope:
$rootScope.globalPopover(a,b,c,d,e,f,g) ;
An alternative to the above, if you don't need it everywhere - like in your app in init/register/startup controllers, is to put all this in your Tabs-Controller.

How to make custom directive with dialog box template using Angular JS?

I need to show a confirmation box on different pages. So i have decided to create a custom directive for performing this task. I have a html template for confirmation box.There are two buttons and some text in this template. One button is for cancelling the dialog box and one for submitting it. So the functionality will be different for each page when we click on submit button. I have couple of questions regarding this issue.
How to create this kind of directive to show a dialog box on some condition?
How to pass text from my controller to this template?
How to override the "Submit" button functionality.
I had similar requirement where I wanted a custom modal pop-up to alert the user to continue with his actions such as delete, modify etc..,
So I wrote a custom directive. Below is the code.
(function(){
'use strict';
angular.module('mainApp').directive('confirm', ['$log','$uibModal', function($log,$uibModal){
var link = function($scope,elem,attr){
elem.bind('click',function(){
var modalInstance = $uibModal.open({
animation: true,
templateUrl: 'templates/shared/_confirm_modal.html',
controller: 'confirmDirectiveCtrl',
size: 'sm'
,backdrop: 'static' //disables modal closing by click on the backdrop.
,resolve: {
requiredVerbose: function(){
var requiredVerbose = {
modalTitle : attr.modalTitle
,message : attr.message
,confirmVerbose : attr.confirmVerbose
,cancelVerbose : attr.cancelVerbose
} ;
return requiredVerbose;
}
}
});
modalInstance.result.then(function(){
$scope.confirmFn();
}, function(){
if($scope.cancelFn){
$scope.cancelFn();
}
});
});
}
return{
restrict : 'A'
,scope : {
confirmFn : '&'
,cancelFn : '&'
}
,compile : function compile(elem,attr){
if(attr.confirmType && attr.confirmType=='delete')
{
attr.modalTitle = 'Warning';
attr.confirmVerbose = 'Delete';
attr.cancelVerbose = 'No';
attr.message = 'Are you sure, you want to delete?'
}
else{
if(!attr.modalTitle){attr.modalTitle = 'Warning'}
if(!attr.confirmVerbose){attr.confirmVerbose = 'Ok'}
if(!attr.cancelVerbose){attr.cancelVerbose = 'cancel'}
if(!attr.message){attr.message = 'Are you sure?'}
}
return{
post : link
}
}
}
}]);
angular.module('mainApp').controller('confirmDirectiveCtrl', ['$scope','$uibModalInstance','requiredVerbose',
function($scope,$uibModalInstance, requiredVerbose){
$scope.modalTitle= requiredVerbose.modalTitle;
$scope.message = requiredVerbose.message;
$scope.confirmVerbose = requiredVerbose.confirmVerbose;
$scope.cancelVerbose= requiredVerbose.cancelVerbose;
$scope.ok = function(){
$uibModalInstance.close($scope.timeline);
};
$scope.cancel = function(){
$uibModalInstance.dismiss();
};
}]);
}());
To answer your questions,
This is attribute type directive. And the element on which you add this directive tag is bound to onclick function which generates the required popup.
How to pass text?
You can pass the required text through attributes. I wanted this directive to work only for two kinds of alerts and hence had only two different sets of texts. If you want custom texts everytime, you can pass them to directive through attrs.
How to override the submit functionality?
You can pass your custom submit and cancel to this directive and bind them to the popup submit and cancel functions. The above code does the same.
Edit :
HTML template and explanation:
Below is an example describing on how you can use this directive.
<i class="fa fa-trash-o"
confirm
confirm-fn="deletePlaylist($index)"
confirm-type="delete">
</i>
The above template is an trash icon. The attributes are
directive name : confirm
confirm-fn : The function that should be called after user seleting ok/submit etc..,
confirm-type : This attribute defines what type of popup you want to show. In my case, I often use 'delete' type and hence wrote the required verbose related to it. By default, I already defined the verbose(title, message, ok-button, cancel-button).
If you want your custom messages add them in the attributes. Below is one such example.
<i class="fa fa-trash-o"
confirm
confirm-fn="doingGreatFn()"
cancel-fn="justFineFn()"
modal-title="My Modal"
message="How are you doing?"
confirm-verbose="Great"
cancel-verbose="Just Fine">
</i>
I hope, this helps
You can create a directive like below to handle both submit & cancel at any page for different functionalities in any controller. I've created an isolated scope directive but you can use change it according to your need by creating child scope scope : true; or bindToController:true (controller specific)
app.directive('confirm', ['$log', '$modal' ,'$parse','$timeout','factory', function($log, $modal,$parse,$timeout,factory) {
return {
restrict: 'E',
template:'<button type="button" class="btn form-btn" '+
'ng-click="openModal()" ng-disabled="disable" >'+
'{{buttonName}}</button>',
replace: true,
transclude: false,
scope: {
name :'=name', //can set button name ..basically u can send a text
disable :'=disable' //set as an attribute in HTML to disable button
},
link: function ($scope, element, attrs) {
$scope.buttonName = $scope.name;
$scope.openModal= function() {
$scope.modal = $modal.open({
templateUrl: 'customConfirmModal.html',
scope:$scope,
persist: true,
backdrop: 'static'
});
};
$scope.cancel = function(){
$scope.modal.dismiss();
};
$scope.submit= function(){
factory.customSubmitCall($scope);//call the factory method which will call different functions depending on the need..
};
}
Create a factory to contain different functions which can be called at any controller by injecting factory.
app.factory('factory', ['$http','$rootScope','$filter',function($http,$rootScope,$filter){
factory.customSubmitCall = function ($scope){
if($rootScope.page ==1){ //check on which page you are performing action
$scope.pageOneSubmit(); //page specific function in that controller..
}else{
$scope.submit();
}
};
return factory;
}]);
In your HTML
<confirm name="Confirm" disable="disable"> </confirm>

Resources