I want to open one $mdDialog
on top of the other. If possible, have unlimited overlapping dialogs.
Any ideas?
I want to open one $mdDialog
on top of the other. If possible, have unlimited overlapping dialogs.
Any ideas?
Yes it's possible, just add "skipHide: true" where you calling mdDialog.. just like:
$scope.xyz = function(anything) {
$mdDialog.show({
controller: "xyzController",
skipHide: true,
templateUrl: 'path-to-partial/xyzDialog.html',
parent: angular.element(document.body),
clickOutsideToClose: true
})
}
Update: this is for angularJs (Angular 1)
skiphide has been deprecated. Use multiple key instead. See documentation here
here is a code snippet
myCtrl.demoClick = function moreInfo(thing) {
$mdDialog.show({
controllerAs: 'dialogCtrl',
clickOutsideToClose: true,
bindToController: true,
controller: function ($mdDialog) {
this.click = function click() {
$mdDialog.show({
preserveScope: true,
multiple: true,
controllerAs: 'dialogCtrl',
controller: function ($mdDialog) {
this.click = function () {
$mdDialog.hide();
}
},
template: '<md-dialog class="confirm"><md-content>I am in a 2nd dialog!<md-button class="md-raised" ng-click="dialogCtrl.click()">Confirm!</md-button></md-content></md-dialog>'
})
}
},
autoWrap: false,
template: '<md-dialog class="stickyDialog" data-type="{{::dialogCtrl.thing.title}}"><md-content>I am in a dialog!<md-button class="md-raised" ng-click="dialogCtrl.click()">Click me to do something</md-button></md-content></md-dialog>',
locals: {
thing: thing
}
})}
As Gabriel Anzaldo Alvarado wrote in the comment, it is possible as you can see on this Plunker: http://plnkr.co/edit/Ga027OYU5nrkua3JxNRy?p=preview
In addition, you can add some css classes to get the same background grey overlay: https://github.com/angular/material/issues/7262
._md-dialog-backdrop:nth-of-type(even) {
z-index: 81;
}
._md-dialog-backdrop:nth-of-type(odd) {
z-index: 79;
}
.md-dialog-container:nth-of-type(even) {
z-index: 80;
}
.md-dialog-container:nth-of-type(odd) {
z-index: 82;
}
UPDATE:
From Angular Material v1.1.2 the option skipHide has been replaced by multiple.
Gabriel Anzaldo Alvarado gave the right answer in my opinion, the correct answer is shared in a Plunker link. But as requested by many users, I'm adding the actual code in case the link becomes unavailable in the future.
Basically, while opening your dialog using the .show({})
function, add the option skipHide: true
.
HTML
<body>
<div ng-controller="AppCtrl as ctrl"
ng-cloak=""
class="virtualRepeatdemoVerticalUsage"
ng-app="MyApp">
<md-content layout="column">
<md-button ng-click="ctrl.moreInfo(1)">
Open Dialog
</md-button>
</md-content>
</div>
</body>
JavaScript
(function () {
'use strict';
angular
.module('MyApp', ['ngMaterial'])
.controller('AppCtrl', function ($interval, $mdDialog) {
var vm = this;
vm.moreInfo = function moreInfo(thing) {
$mdDialog.show({
controllerAs : 'dialogCtrl',
clickOutsideToClose : true,
bindToController : true,
controller : function ($mdDialog) {
this.click = function click() {
$mdDialog.show({
controllerAs : 'dialogCtrl',
controller : function ($mdDialog) {
this.click = function () {
$mdDialog.hide();
}
},
preserveScope : true,
autoWrap : true,
skipHide : true,
template : '<md-dialog class="confirm"><md-content><md-button ng-click="dialogCtrl.click()">I am in a 2nd dialog!</md-button></md-content></md-dialog>'
})
}
},
autoWrap : false,
template : '<md-dialog class="stickyDialog" data-type="{{::dialogCtrl.thing.title}}"><md-content><md-button ng-click="dialogCtrl.click()">I am in a dialog!</md-button></md-content></md-dialog>',
locals : {
thing : thing
}
})
}
});
})();
The code above worked for me.
As noted by Vincenzo in another answer, while stacking mdDialogs, the dialogs beneath will not grey-out, there is a CSS trick to solve that: https://stackoverflow.com/a/38013682/366662
UPDATE
This answer works for version 1.1.1, from version 1.1.2 the Material team changed the property from skipHide
to multiple
. So, be careful when copy-pasting the snippet. Check your Material version and use the correct property accordingly.
in the latest AngularJs Material dialog, you can find this solution: https://material.angularjs.org/latest/api/service/$mdDialog#multiple-dialogs
It uses multiple dialog preset or configuration.
Absolutely not possible.* for now. It is understandable for some situations but other way is needed too. So, I preferred to use custom popup dialogs variates for same functionalities. Otherwise md-dialog gives pain to doing job.
I got this to work with very little effort and a bit of angular hacking.
To make things clear, I'm using Angular v1.5.3 & Angular Material v1.0.6.
With previous versions if you add skipHide: true
to your dialog definition object, it will allow multiple dialogs. Your issue then comes to the cancel button which will close the wrong dialog box.
The solution is rather calling $mdDialog.cancel
we want to call $mdDialog.hide
as it correctly resolves the right dialog box. Rather than making sure you have setup every instance correctly, or even making sure 3rd party libs also follow this pattern, we can decorate the $mdDialogProvider
.
$provide.decorator
$provide.decorator(name, decorator);
Register a service decorator with the $injector. A service decorator intercepts the creation of a service, allowing it to override or modify the behavior of the service. The object returned by the decorator may be the original service, or a new service object which replaces or wraps and delegates to the original service.
angular.module('module').config(function($provide) {
$provide.decorator('$mdDialog', function($delegate) {
var methodHandle = $delegate.show;
function decorateDialogShow() {
var args = angular.extend({}, arguments[0], {
skipHide: true
});
return methodHandle(args);
}
$delegate.show = decorateDialogShow;
$delegate.cancel = function() {
return $delegate.hide(null);
}
return $delegate;
});
});
The above will simply replace the cancel method, with the existing and working hide method. Also sets a global default so that skipHide is set initially on all dialog boxes.
Winner winner!
UPDATE: As per @Magnus, it was updated to multiple
as of v1.1.2
Add skipHide: true
to the second dialog's options object.
This works for me: http://webiks.com/mddialog-with-a-confirmation-dialog/
$mdDialog.show({
parent: angular.element(document.body),
templateUrl: 'template.html',
clickOutsideToClose: true,
fullscreen: true,
preserveScope: true,
autoWrap: true,
skipHide: true,
controllerAs: 'customDialog',
controller: function ($mdDialog) {
this.callNewDialog = function (dialogCallback) {
dialogCallback();
};
}});
call in view:
ng-click="customDialog.callNewDialog(vm.addNewCustomer)"
and vm.addNewCustomer
will be a function that open new dialog
Actually you can use mdPanels. Little snippet:
return $q(function(resolve, reject){
$mdPanel.open(Object.assign({
hasBackdrop: true,
zIndex: 85, //greater than modal and lower than autocomplete\select
locals: Object.assign({
onClose: resolve
}, locals),
template: getCommonTemplate(template, heading),
bindToController:true,
controller: 'PanelDummyController as $ctrl',
panelClass: 'rl-modal-panel',
position: $mdPanel.newPanelPosition()
.absolute()
.center()
}))
});
controller('PanelDummyController', function (mdPanelRef) {
'ngInject';
const close = () => mdPanelRef.close().then(() => {
this.onClose(Object.assign({}, this));
});
this.$mdDialog = {
cancel: close,
hide: close
};
});
and add little styling to class. It's not fully copy of modal, but it's quite good implementation and could be improved to fully copy.
Here is a workaround to have nested dialogs.
The idea is when the second is open save the state of the first, and when the second is closed launch the first dialog again.
No, it is not possible right now to have multiple
$mdDialog
. Honestly I really need this feature and tried it to get it to work but no success so far. Lets hope they allow this feature in future releases.Although there is discussion here, you can find something useful there.
NOTE: This is no longer the correct answer, as opposed to the time period it was answered, look below for more answers.