Material: md-dialog: All confirm dialog buttons are using md-primary

Created on 4 May 2015  路  13Comments  路  Source: angular/material

In 0.9.0-rc3 all the prefab dialog's buttons are using md-primary.

See the dialog demo click on confirm dialog since it has 2 options
https://material.angularjs.org/#/demo/material.components.dialog
image

The Sounds like a scam cancel button should not have md-primary.

works as expected

Most helpful comment

Its seems there is no option to change the style since you use the mdDialog service (without custom template).

Anyway, I found some work around, that can be helpful.
"onComplete" property (see docs => search: "onComplete")

onComplete {function=}: Callback function used to announce when the show() action is finished.

You can insert an option object into you dialog definition such as:

var confirm = $mdDialog.confirm({
                    onComplete: function afterShowAnimation() {
                        var $dialog = angular.element(document.querySelector('md-dialog'));
                        var $actionsSection = $dialog.find('md-dialog-actions');
                        var $cancelButton = $actionsSection.children()[0];
                        var $confirmButton = $actionsSection.children()[1];
                        angular.element($confirmButton).addClass('md-raised md-warn');
                        angular.element($cancelButton).addClass('md-raised');
                    }
                })
                .title('my title'))
                .textContent('myContent')
                .ariaLabel('my aria label')
                .ok('Please, DO it!')
                .cancel("It's big decision for me, so NO!");

Then show your dialog:

$mdDialog
       .show(myConfirm)
       .then(...);

All 13 comments

This was covered a little while ago. It follows the spec images here: http://www.google.com/design/spec/components/dialogs.html#
Notice how all the button colors are the same even if it's positive/negative

I thought it was against the spec since we had it the other way for so long. Sorry about this.

Still seems strange, considering that "Cancel" shouldn't be a primary action. This has confused many of our users. :\

Is there any option to change the cancel color?

Its seems there is no option to change the style since you use the mdDialog service (without custom template).

Anyway, I found some work around, that can be helpful.
"onComplete" property (see docs => search: "onComplete")

onComplete {function=}: Callback function used to announce when the show() action is finished.

You can insert an option object into you dialog definition such as:

var confirm = $mdDialog.confirm({
                    onComplete: function afterShowAnimation() {
                        var $dialog = angular.element(document.querySelector('md-dialog'));
                        var $actionsSection = $dialog.find('md-dialog-actions');
                        var $cancelButton = $actionsSection.children()[0];
                        var $confirmButton = $actionsSection.children()[1];
                        angular.element($confirmButton).addClass('md-raised md-warn');
                        angular.element($cancelButton).addClass('md-raised');
                    }
                })
                .title('my title'))
                .textContent('myContent')
                .ariaLabel('my aria label')
                .ok('Please, DO it!')
                .cancel("It's big decision for me, so NO!");

Then show your dialog:

$mdDialog
       .show(myConfirm)
       .then(...);

+1

In case it helps someone, here's how I fixed it to work on onShowing instead of onComplete.

 var fixButtons = function() {
    console.log("fixButtons");
    var foundCancelButton = false;
    var $dialog = angular.element(document.querySelector('md-dialog'));
    var $actionsSection = $dialog.find('md-dialog-actions');
    var $cancelButton = $actionsSection.children()[0];
    var $confirmButton = $actionsSection.children()[1];
    angular.element($confirmButton).addClass('md-raised md-warn');
    if($cancelButton)
    {
      foundCancelButton = true;
      var cancelElement = angular.element($cancelButton);
      cancelElement.removeClass('md-primary');
      cancelElement.addClass('my-custom-class');
    }

    return foundCancelButton;
  }
  var dialog = $mdDialog.prompt({
    onShowing: function onShowAnimation() {
      console.log("fixButtons0");
      if(!fixButtons())
      {
        console.log("fixButtons1");
        $timeout(function(){
          fixButtons();
         });            
      }
    },
    onComplete: function afterShowAnimation() {
      fixButtons();
    }
  })
  .title('Dialog Title')
  .textContent('Text Content')
  .placeholder("Placeholder")
  .ariaLabel('AriaLabel')
  .targetEvent(event)
  .ok('Save')
  .cancel('Cancel');

  $mdDialog.show(dialog)
  .then(function(result) 
  {
  }, function() {
  });

Having the same issue on it right now. The above answers are a big additional in my code, just to make the button "raised". I think it is much better to make ok() raised by default.

I was having the same problem and ran into a couple issues with the above solutions mainly because they only seem to apply to the last dialog created on the page not parent directives etc... This was overcome by using the function parameter rather than a document.querySelector. Also I agree with @jmaicaaan that this code is bulky for everytime I need to modify the classes of the built in dialogs which were fine for most of my purposes except the styling. A fairly clean solution is to put this code in a service and then apply new styles to the prompt in a single line:

$mdDialog.prompt(DialogHelper.warn());

or specify the cancel and confirm classes explicitly:

$mdDialog.prompt(DialogHelper.addClasses('md-raised','md-raised md-warn'));

Here is the service:

angular.module('app').service('DialogHelper', [
    '$timeout',
    function($timeout) {
        var doClassAddition = function($dialog, cancel, confirm) {
            console.log($dialog);
            angular.element($dialog.find('md-dialog-actions').children()[0]).addClass(cancel);
            angular.element($dialog.find('md-dialog-actions').children()[1]).addClass(confirm);
        };

        var addClasses = function(cancel, confirm) {
            return {
                onShowing: function(scope, element, options, controller) {
                    // keep original functionality
                    if (controller) {
                        var mdHtmlContent = controller.htmlContent || options.htmlContent || '';
                        var mdTextContent = controller.textContent || options.textContent || controller.content || options.content || '';
                        if (mdHtmlContent && !$injector.has('$sanitize')) {
                            throw Error('The ngSanitize module must be loaded in order to use htmlContent.');
                        }
                        if (mdHtmlContent && mdTextContent) {
                            throw Error('md-dialog cannot have both `htmlContent` and `textContent`');
                        }
                        controller.mdHtmlContent = mdHtmlContent;
                        controller.mdTextContent = mdTextContent;
                    }
                    // add our custom stuff
                    $timeout(function() {
                        doClassAddition(element, cancel, confirm);
                    });
                }
            }
        }
        var warn = function() {
            return addClasses('', 'md-raised md-warn');
        }
        var accent = function() {
            return addClasses('', 'md-raised md-accent');
        }
        return {accent: accent, warn: warn, addClasses: addClasses}
    }
]);

Here is my version of the workaround:

var confirm = $mdDialog.confirm({onComplete: function() {
                        angular.element(document.querySelector("button[ng-click='dialog.hide()']")).addClass('md-raised md-warn');
                        angular.element(document.querySelector("button[ng-click='dialog.abort()']")).addClass('md-raised');
                    }})

It's based on @naorz 's version but a bit shorter and more generic.

Issue is not related with Button, But One issue which I am facing is that how can I pass parameter to my confirm dialog. Suppose I have grid and there are delete buttons. After clicking on a delete button Confirm dialog appears and I want to delete that particular record.
Is it possible with Confirm Or I should use custom mddialog?

@rbhargava25 you can't pass data into confirm dialogs. You shouldn't need a custom dialog for that use case though. You just need to keep a reference to the item that was clicked, then use that if the confirm dialog's Promise is resolved.

If you have additional questions about how dialogs work, please try Stack Overflow, Gitter, or the AngularJS Material forums.

Was this page helpful?
0 / 5 - 0 ratings