Material: Enhancement to open multiple dialogs using $mdDialog

Created on 3 Jun 2016  路  28Comments  路  Source: angular/material

Hello,

I am inquiring to find out whether or not there are plans to add functionality to the $mdDialog service for showing multiple dialogs. I am aware of this thread but I'd like to rekindle the discussion.

My specific need is that my application requires a virtual keyboard. I implemented this virtual keyboard using a wrapper service around $mdDialog (and a separate directive). This worked flawlessly...up until the point I tried to apply my virtual keyboard to an input that's inside of a dialog. Once the user clicks the input within the dialog it goes away and up comes the keyboard.

1) Is there any chance that having multiple dialogs will be implemented in the future?
2) Does anyone have suggestions for working around this limitation?

I found the options $mdDialog provides to be extremely useful, so it's disappointing to rearrange my architecture and try to recreate the niceties myself.

showKeyboard(keyboardType, inputElement, modelUpdateEvent, customValidation) {
      var s = this;
      let positionKeyboard = () => {
        $('#keyboard-dialog').position({
          of: $(inputElement),
          my: "right top",
          at: "right bottom",
          collision: "flipfit flipfit"
        });
        s._isDragging = false;
        let dragDelay = 1000;
        let dragTimeout = undefined;
        $('#keyboard-dialog').on("mousedown", () => {
          if(s._isDragging == false) {
            dragTimeout = this._$timeout(() => {
              s._isDragging = true;
              s._dragStartTime = moment();
              let draggingMask = $.parseHTML(`<div class="drag-mask"></div>`);
              $(draggingMask).css({
                position: 'absolute',
                width: '100%',
                height: '100%',
                top: '0px',
                left: '0px',
                zIndex: 100
              });
              $('#keyboard-dialog').append(draggingMask);
              $('#keyboard-dialog').css({
                border: '3px solid rgb(86, 180, 239)',
                'box-shadow': '0px 1px 3px rgba(0, 0, 0, 0.05) inset, 0px 0px 8px rgba(82, 168, 236, 0.6)'
              });
              $('#keyboard-dialog').draggable();
            }, dragDelay);
          }
        });

        $('#keyboard-dialog').on("mouseup", () => {
          if(angular.isDefined(dragTimeout)) {
            s._$timeout.cancel(dragTimeout);
            dragTimeout = undefined;
          }
          let now = moment();
          let timespan = moment.duration(now.diff(s._dragStartTime));
          if($(".drag-mask").length && s._isDragging && timespan.asMilliseconds() > 700) {
            s._isDragging = false;
            $(".drag-mask").remove();
            $('#keyboard-dialog').css({
              border: 'none',
              'box-shadow': 'none'
            });
            $('#keyboard-dialog').draggable("destroy");
          }
        });
      };

      this._$mdDialog.show({
        templateUrl: 'partials/dialogs/keyboard/keyboardDialog.html',
        controller: 'keyboardDialogController as vm',
        clickOutsideToClose: true,
        hasBackdrop: false,
        //openFrom: inputElement,
        closeTo: inputElement,
        onComplete: positionKeyboard,
        locals: {
          keyboardType: keyboardType,
          inputElement: inputElement,
          modelUpdateEvent: modelUpdateEvent,
          customValidation: customValidation
        }
      })
      .then(
        () => { $(inputElement).trigger("blur"); },
        () => { $(inputElement).trigger("blur"); }
      );
    }
- Lots of Comments important Pull Request fixed enhancement

Most helpful comment

@olingern - Exactly skipHide will be renamed to multiple.

  • Once multiple is disabled (by default), the previous interim, when a new interim will be shown, will hide properly. (This was not the case before - overlapping toasts e.g)
  • Keeping track of interims, which are currently opening | open | closing.
    This allows us to properly support cancellation / hiding of multiple interims.

All 28 comments

We do not have plans to support it the new future. But we will create the base for multiple interim elements (like the dialog) in #8624. So once #8624 is ready, we'll probably revisit the multiple dialogs issue.

Alright, understood. Thanks for the quick feedback =)

@DevVersion Will you let us know here if you finally manage to revisit the multiple dialogs issue?

@jaymanned Definitely yes! It's just a lower priority on my queue for now, but will definitely revisit that issue.

Copying and pasting my comment from #3072 for others who may stumble upon this or are unaware of existing functionality:


Unsure why this isn't documented, but using skipHide on the child dialog will allow this.

Here's a plunker

And here's the line of code that "skips" hiding the parent dialog.

@olingern This is not documented, because it's currently only internal and designed for use with the $mdMenu.

In #9053, skipHide` has been redesigned to properly handle multiple interims at the same time.

@DevVersion I see... and awesome. Thanks for your work on this!

So as of #9053 you migrate skipHide to multiple and keep a stack of shown interim elements?

@olingern - Exactly skipHide will be renamed to multiple.

  • Once multiple is disabled (by default), the previous interim, when a new interim will be shown, will hide properly. (This was not the case before - overlapping toasts e.g)
  • Keeping track of interims, which are currently opening | open | closing.
    This allows us to properly support cancellation / hiding of multiple interims.

Thanks for this. Super helpful for confirmations when inside a modal. I'm sure #698, #3072 will welcome the changes, too. Cheers.

Hello guys, just wanted to let you know, that multiple dialogs are right now supported, but not documented yet.

Using the multiple: true option, does ensure dialogs will not close the previous showing dialog.

Great. Thanks. So it's now part of release 1.1.1?

It will be available in the next release. Right now its only in master.

Awesome, thank you!

This is awesome news, thank you so much!

Are we not able to use .multiple(true) on confirm dialogs?

@warent You should be able to do that.

Hello. Is this option part of release 1.1.1 yet?

Thx for the good work

@DevVersion Not works with confirm().multiple(true) on 1.1.1

@trinvh It doesn't work because it hasn't been released as part of v1.1.1.

The feature is included in v.1.1.2

Well done @DevVersion

This works for me:

var confirmDialog = $mdDialog.confirm({
multiple: true
});

$mdDialog.show(confirmDialog)

Great! It worked for me.

I am not able to use $mdDialog.prompt({
multiple: true
});

what am i doing wrong ?

@jainpiyush111 - I haven't tested on the prompt(), but on confirm() you would do it this way, which is probably very similar for prompt:

        var confirmDialog = $mdDialog.confirm()
            .title('Please confirm')
            .textContent('Are you sure you want to delete this message?')
            .ariaLabel('Delete confirmation dialog')
            .ok('Yes')
            .cancel('No')
            .multiple(true);

        $mdDialog.show(confirmDialog).then(function() {

.. FYI - I'm on v1.1.3

For confirm and alert dialog, it'll be better to use .parent with skipHide/multiple:

        var confirmDialog = $mdDialog.confirm({skipHide/multiple: true})
            .title('Please confirm')
            .textContent('Are you sure you want to delete this message?')
            .parent(angular.element(document.querySelector('#parentDialog')))
            .ok('Yes')
            .cancel('No')
            .multiple(true);

        $mdDialog.show(confirmDialog).then(function(){}

skipHide for older versions & multiple for newer...

I am using 1.1.4 and this is my codes:
$mdDialog.show(
{ multiple: true, ..... }
);

It didn't work, any reason?

Not sure about your version, but I'm on 1.1.7 and it works well.

Thanks. Solved.

Was this page helpful?
0 / 5 - 0 ratings