how can I change the color of Toast depends on message type in Angular material $mdToast?

AngularjsMaterial DesignToastAngular Material

Angularjs Problem Overview


While using $mdToast.simple().content("some test") it is showing the toast with black color. how can I change that color to red, yellow and so, depends on the type of the error messages like error, warning and success.

Similar question as this.

Angularjs Solutions


Solution 1 - Angularjs

There is an easier way by specifying a theme:

$mdToast.simple().content("some test").theme("success-toast")

And in your CSS:

md-toast.md-success-toast-theme {
    background-color: green;
    ...
}

You could incorporate your message type to dynamically select a theme.

Update: As Charlie Ng pointed out, to avoid warnings regarding use of an unregistered custom theme register it in your module using the theme provider: $mdThemingProvider.theme("success-toast")

Another update: There was a breaking change created on 2 Dec 2015 (v1.0.0+). You now need to specify:

md-toast.md-success-toast-theme {
    .md-toast-content {
        background-color: green;
        ...
    }
}

Solution 2 - Angularjs

EDIT:
For a correct implementation, please use rlay3s solution below :)!

OUTDATED:
I had problems displaying custom text with jhblacklocks solution, so I decided to do it like this using 'template':

var displayToast = function(type, msg) {

    $mdToast.show({
        template: '<md-toast class="md-toast ' + type +'">' + msg + '</md-toast>',
        hideDelay: 6000,
        position: 'bottom right'
    });
};

I also added the different types in my .css file:

.md-toast.error {
    background-color: red;
}

.md-toast.success {
    background-color: green;
}

Don't know if this is the most beautiful approach, but I don't need a template files for each dialog type and displaying custom text is really easy.

Solution 3 - Angularjs

register themes:

$mdThemingProvider.theme("success-toast");
$mdThemingProvider.theme("error-toast");

add css:

md-toast.md-error-toast-theme div.md-toast-content{
    color: white !important;
    background-color: red !important;
}

md-toast.md-success-toast-theme div.md-toast-content{
    color: white !important;
    background-color: green !important;
}

use:

$mdToast.show(
    $mdToast.simple()
        .content(message)
        .hideDelay(2000)
        .position('bottom right')
        .theme(type + "-toast")
);

Solution 4 - Angularjs

You can see on this link that you cannot change the background color of the element, it'll be always fixed:

https://github.com/angular/material/blob/master/src/components/toast/toast-theme.scss

This is because the Material Design Guidelines for Toasts states that the background will always remains the same:

https://www.google.com/design/spec/components/snackbars-toasts.html#snackbars-toasts-specs

Note the background item on the Specs list.

Nothing is said about the text color in each situation, it's implied that it follows the backgroundPalette, on the '50' hue rotation, declared on that CSS on the GitHub Link.

The way to distinct a warn toast, or an accent-ted one, from the default, calling an action toast, each with its action button using the appropriate class (md-warn or md-accent).

$mdToast.show({
    template: '<md-toast>\
        {{ toast.content }}\
        <md-button ng-click="toast.resolve()" class="md-warn">\
            Ok\
        </md-button>\
    </md-toast>',
    controller: [function () {
        this.content = 'Toast Content';
    }],
    controllerAs: 'toast'
});

The toast itself, which its default form means an action report, with success implied. If it needs more even more attention, force its close by setting up an action button add actions like 'Retry', 'Report a problem', 'Details', which can be used to catch this click and record some technical info, etc... the examples vary from what you need.

Solution 5 - Angularjs

One more step to rlay3's answer.

Angular Material at 0.7.1 added warning to unregistered themes. https://github.com/angular/material/blob/master/CHANGELOG.md#071--2015-01-30

If theme is not registered, every time the toast shows up, you will be getting a warning message in console like, for example:

attempted to use unregistered theme 'custom-toast'
angular.js:12416 Attempted to use unregistered theme 'custom-toast'. 
Register it with $mdThemingProvider.theme().

To get rid of the warning, you will need to configure the theme 'custom-toast' in your angular app:

angular.module('myApp', ['ngMaterial'])
.config(function($mdThemingProvider) {
  $mdThemingProvider.theme('custom-toast')
});

and use it like:

$mdToast.simple().content("some test").theme("custom-toast");

references: https://material.angularjs.org/latest/#/Theming/04_multiple_themes

Solution 6 - Angularjs

You did ask about using the simple toast call. Would you mind trying a custom toast show like the demo and add classes to the template?

JS

$mdToast.show(
  controller: 'ToastCtrl',
  templateUrl: 'views/shared/toast.html',
  hideDelay: 6000,
  position: $scope.getToastPosition()
)

TEMPLATE

<md-toast class="flash">
  <span flex>Custom toast!</span>
  <md-button ng-click="closeToast()">
   Close
  </md-button>
</md-toast>

CSS

md-toast.flash {
  background-color: red;
  color: white;
}

CONTROLLER (COFFEE)

'use strict'

###*
 # @ngdoc function
 # @name angularApp.controller:ToastCtrl
 # @description
 # # ToastCtrl
 # Controller of the angularApp
###
angular.module('angularApp')
  .controller 'ToastCtrl', ($scope) ->
    $scope.closeToast = ()->
      $mdToast.hide()

 

Solution 7 - Angularjs

Just to give another option, $mdToast allows to define toast presets that you can easily instantiate in this way, though i'm struggling to understand how to change the text content, any idea?

$mdToast.show(
  $mdToast.error()
);

The presets are defined as explained on https://material.angularjs.org/latest/api/service/$mdToast :

$mdToastProvider.addPreset('error', {
  options: function() {
    return {
      template:
        '<md-toast>' +
          '<div class="md-toast-content">' +
          '</div>' +
        '</md-toast>',
      position: 'top left',
      hideDelay: 2000,
      toastClass: 'toast-error',
      controllerAs: 'toast',
      bindToController: true
    };
  }
});

Solution 8 - Angularjs

I first favoured the solution but I don't like setting up a theme in the theme provider just for a toast. So how about this solution:

JS (Coffee)

   if error
      message = ''

      if error.reason is 'Incorrect password'
        message = 'Email and password combination is incorrect'
      if error.reason is 'User not found'
        message = 'No account found with this email address'

      $mdToast.show(
        templateUrl:  'client/modules/toasts/toastError.html'
        hideDelay:    3000
        controller: ( $scope ) ->
          $scope.message    =  message
          $scope.class      = 'error'
          $scope.buttonLabel = 'close'
          $scope.closeToast = ->
            $mdToast.hide()
      ).then( ( result ) ->
        if result is 'ok'
          console.log('do action')
      )

and then HTML (JADE)

md-toast(ng-class="class")
  span(flex) {{message}}
  md-button.md-action(ng-click="closeToast()") {{buttonLabel}}

I tried to use the locals option to pass variables to the controller, but for some reason they are not injected.(https://material.angularjs.org/latest/#/api/material.components.toast/service/$mdToast check list of options under show function)

Then last the CSS (STYLUS)

md-toast.success
  background-color    green

md-toast.error
  background-color    red

Summary: there is on template in this case which you can give custom placeholders which you prefill in your controller. This solution works for me.

Solution 9 - Angularjs

You can do it with factory and some css.

(function () {
  'use strict';

  angular
    .module('app.core')
    .factory('ToastService', ToastService);

  /** @ngInject */
  function ToastService($mdToast) {

    var service = {
      error: error,
      success: success,
      info : info
    };

    return service;

    //////////

    function success(text) {
      $mdToast.show(
        $mdToast.simple()
          .toastClass("toast-success")
          .textContent(text)
      );
    }

    function info(text) {
      $mdToast.show(
        $mdToast.simple()
          .toastClass("toast-info")
          .textContent(text)
      );
    }

    function error(text) {
      $mdToast.show(
        $mdToast.simple()
          .toastClass("toast-error")
          .textContent(text)
      );
    }
  }
}());

And css.

.toast-error .md-toast-content{
  background-color: rgb(102,187,106) !important;
}

.toast-info .md-toast-content{
  background-color: rgb(41,182,246) !important;
}

.toast-error .md-toast-content{
  background-color: rgb(239,83,80) !important;
}

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionRafiuView Question on Stackoverflow
Solution 1 - Angularjsrlay3View Answer on Stackoverflow
Solution 2 - Angularjsnovas1r1View Answer on Stackoverflow
Solution 3 - AngularjsmattatworkView Answer on Stackoverflow
Solution 4 - AngularjsMateus LeonView Answer on Stackoverflow
Solution 5 - AngularjsCharlie NgView Answer on Stackoverflow
Solution 6 - AngularjsjhblacklockView Answer on Stackoverflow
Solution 7 - AngularjsLuca FaggianelliView Answer on Stackoverflow
Solution 8 - AngularjsMattijsView Answer on Stackoverflow
Solution 9 - AngularjshurricaneView Answer on Stackoverflow