Skip to content
This repository has been archived by the owner on Sep 5, 2024. It is now read-only.

Open multiple dialogs? #698

Closed
9uenther opened this issue Nov 20, 2014 · 36 comments
Closed

Open multiple dialogs? #698

9uenther opened this issue Nov 20, 2014 · 36 comments

Comments

@9uenther
Copy link

I would like to open multiple layered dialogs from each controller. Is this possible?
Currently if i open a second dialog, the first one closes automatically.

@marcysutton
Copy link
Contributor

Currently you can only open one dialog at a time. According to the Material Design spec, whether multiple dialogs should be allowed depends on the context and type of dialog:

Avoid opening additional dialogs from within a dialog.

Full-screen dialogs may open additional dialogs, such as pickers, because their design accommodates additional layers of material without significantly increasing the perceived z-depth of the app or increasing visual noise.

Avoid creating dialogs with scrolling content, particularly alerts. Instead, consider alternate containers or layouts that are optimized for reading or interacting with significant amounts of content.

https://www.google.com/design/spec/components/dialogs.html#dialogs-content

@ThomasBurleson ThomasBurleson changed the title QUESTION ... Is it possible to open multiple dialogs? Open multiple dialogs? Nov 20, 2014
@ThomasBurleson
Copy link
Contributor

@marcysutton, @fhrtms - there have been discussions regarding extensions to $$interimService to cache a LIFO-stack of dialogs; where the hide() will pop off the most recent and hide/close that instance.

@marcysutton
Copy link
Contributor

@ThomasBurleson ahh! Apologies for prematurely closing. That sounds like similar behavior to the "escape stack" we discussed for Sidenav & Bottom Sheet.

@ThomasBurleson
Copy link
Contributor

@marcysutton - exactly. After you indicated that the Spec loosely allows mulitple dialogs, I thought we should formally add the feature to Angular Material.

@marcysutton
Copy link
Contributor

@ThomasBurleson it says "[f]ull-screen dialogs may open additional dialogs, such as pickers, because their design accommodates additional layers". That leaves me with a few spec questions:

  1. Can a dialog can trigger another dialog as long as it's smaller, and you're in a full-screen experience? What happens on smaller screens?
  2. Can multiple dialogs be triggered from a page? When one dialog closes, is focus sent to the next dialog?

@ThomasBurleson
Copy link
Contributor

👍 for excellent questions.

@ajoslin
Copy link
Contributor

ajoslin commented Nov 20, 2014

There's also the iOS style: if a popup opens while another is already open, it will temporarily hide the first popup, show the new popup until the user is done interacting with the new popup, then show the first popup again.

@ThomasBurleson
Copy link
Contributor

👏 - I really like that idea also. Sounds like an option flag currentDialog: hide || close || overlay

@ThomasBurleson
Copy link
Contributor

Consider $timeout() which returns a promise and the `$timeout.cancel( ) is used to cancels a task associated with the promise.

Since $mdDialog.show() returns a promise, perhaps, $mdDialog.close( <promise> ) could be used to close a specific dialog instance.

@brettstack
Copy link
Contributor

Another use case?:
I often use modals for create/update forms and I often need to show a confirmation message. Although this is probably better handled by a bottom sheet now. Is this correct?

@ThomasBurleson
Copy link
Contributor

Or you can use Toast components to show transient messages.

@brettstack
Copy link
Contributor

I should have been more clear. By confirmation message, I mean a dialog with "OK", "Cancel" options. Toast messages aren't obvious enough for this purpose, but I do use them to show e.g. a successful save message.

@9uenther
Copy link
Author

9uenther commented Dec 9, 2014

I'm found a nice way to use one dialog with back reference to the parent.

Image of Yaktocat

/* BERABEITUNGSDIALOG */
$scope.dialogEditor = function(ev, item) {
    var item = angular.copy(item);
    $scope.editDialog = $mdDialog;
    $scope.editDialog.show({
        templateUrl: 'app/views/myDialog.html',
        clickOutsideToClose: false,
        locals: {local: [$scope.db, item, $scope.editDialog, $scope]},
        controller: ['$scope', '$mdDialog', '$mdToast', 'socket', 'local', myDialogController]
    }).then(function() {
        $scope.alert = 'You said "Okay".';
    }, function() {
        $scope.alert = 'You cancelled the dialog.';
    });
};


var myDialogController = function ($scope, $mdDialog, $mdToast, socket, local) {
    $scope.dialog = local[3].dialogEditor;

    /* DATENSATZ LOESCHEN */
    $scope.deleteData = function() {
        var confirm = $mdDialog.confirm()
            .title('Möchtest Du den zuvor gewählten Datensatz wirklich löschen?')
            .content('Wenn Du dir NICHT sicher bist, dann tippe einfach auf \'NEE, LIEBER DOCH NICHT\' und fahre mit der Bearbeitung fort.')
            .ok('Ja, jetzt löschen')
            .cancel('Neee, lieber doch nicht');

        $mdDialog.show(confirm).then(function() {
            $scope.saveData({delete: true});
        }, function() {
            //$scope.dialogClose();
            $scope.dialog(null, local[1]); /* DATENSATZ ZURUECKGEBEN */
        });
    };
´´´

@brettstack
Copy link
Contributor

Thanks for sharing. What tool do you use to capture those gifs?
On 9 Dec 2014 02:28, "fhrtms" [email protected] wrote:

I'm found a nice way to use one dialog with back reference to the parent.

[image: Image of Yaktocat]
https://camo.githubusercontent.com/93e2c74cf5c2f8cca68d73dcf28a5a4f094978a1/687474703a2f2f692e696d6775722e636f6d2f4e423258774e342e6769663f31

/* BERABEITUNGSDIALOG */
$scope.dialogEditor = function(ev, item) {
var item = angular.copy(item);
$scope.editDialog = $mdDialog;
$scope.editDialog.show({
templateUrl: 'app/views/myDialog.html',
clickOutsideToClose: false,
locals: {local: [$scope.db, item, $scope.editDialog, $scope]},
controller: ['$scope', '$mdDialog', '$mdToast', 'socket', 'local', myDialogController]
}).then(function() {
$scope.alert = 'You said "Okay".';
}, function() {
$scope.alert = 'You cancelled the dialog.';
});
};

var myDialogController = function ($scope, $mdDialog, $mdToast, socket, local) {
$scope.dialog = local[3].dialogEditor;

/* DATENSATZ LOESCHEN */
$scope.deleteData = function() {
    var confirm = $mdDialog.confirm()
        .title('Möchtest Du den zuvor gewählten Datensatz wirklich löschen?')
        .content('Wenn Du dir NICHT sicher bist, dann tippe einfach auf \'NEE, LIEBER DOCH NICHT\' und fahre mit der Bearbeitung fort.')
        .ok('Ja, jetzt löschen')
        .cancel('Neee, lieber doch nicht');

    $mdDialog.show(confirm).then(function() {
        $scope.saveData({delete: true});
    }, function() {
        //$scope.dialogClose();
        $scope.dialog(null, local[1]); /* DATENSATZ ZURUECKGEBEN */
    });
};

´´´


Reply to this email directly or view it on GitHub
#698 (comment).

@9uenther
Copy link
Author

9uenther commented Dec 9, 2014

I like this one on Windows:
screentogif.codeplex.com

No install, very handy and easy to use!

and this on Linux:
recorditnow.sourceforge.net

@marcospgp
Copy link

@fhrtms thanks for that code! It took me a while to figure out what you were doing since there were no english comments but it seems you are just saving the main dialog's scope before opening the second dialog, and then if the user cancels this second one, you just reopen the main with the old scope, is that right?
I'm going to do it a bit differently from you, but the idea remains the same. Thanks a lot!

@9uenther
Copy link
Author

9uenther commented Jan 8, 2015

@marcosportugal: Yes, this is what i do.

@benn0r
Copy link

benn0r commented Jan 13, 2015

I really need nested dialogs for our application, so i tinkered with the source code. I didn't test it very well but i think its working, at least for us. Its a quick solution (manipulating the z-index like i do is not very nice, i guess).

If a new dialog opens, old dialogs won't close. If $mdDialog.cancel() is called the most recent dialog will be closed.

hayloft@2ad189a
Obviously some unit tests break with this commit...

Updated for 0.8.3: hayloft@1650734

@paynecodes
Copy link
Contributor

Has anyone from core team been able to try out @benn0r's code? The change seems easy to digest.

@robertmesserle robertmesserle modified the milestones: 0.9.0, 0.8.0 Feb 19, 2015
@ThomasBurleson ThomasBurleson modified the milestones: 0.10.0, 0.11.0 Jun 16, 2015
@everlaat
Copy link

+1

@websirnik
Copy link

+1.
I like this idea: #698 (comment):

Sounds like an option flag currentDialog: hide || close || overlay

Assume: If the original dialog is scrollable, and the trigger for the new dialog is somewhere inside the scrollable container.
When the child dialog is closed, I would like to be returned back to the position of the trigger inside the scrollable container of the original dialog.

@ishener
Copy link

ishener commented Jul 6, 2015

+1

@dyatchenko
Copy link

I would be really glad to have this issue fixed.

@kikhtenko
Copy link

+1

1 similar comment
@edicius6
Copy link

+1

@ThomasBurleson
Copy link
Contributor

Locking this issue until it becomes active, in-progress.

@angular angular locked and limited conversation to collaborators Jul 10, 2015
@ThomasBurleson ThomasBurleson modified the milestones: 0.11.0, post-1.0 Jul 31, 2015
@ThomasBurleson ThomasBurleson modified the milestone: post-1.0 Aug 10, 2015
@ThomasBurleson ThomasBurleson modified the milestones: post-1.0 , Backlog Jan 5, 2016
@ginader
Copy link

ginader commented Mar 11, 2016

any update on this @ThomasBurleson?

@ThomasBurleson ThomasBurleson modified the milestones: Backlog, Deprecated Apr 20, 2016
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests