<!DOCTYPE html>
<html>

  <head>
    <meta charset="UTF-8" />
    <title>AngularJS - Nifty Toast</title>
    <link data-require="bootstrap-css@*" data-semver="3.3.1" rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.1/css/bootstrap.min.css" />
    <script src="//ajax.googleapis.com/ajax/libs/angularjs/1.3.14/angular.min.js"></script>
    <script src="http://angular-ui.github.io/bootstrap/ui-bootstrap-tpls-0.12.0.js"></script>
    <script src="script.js"></script>
  </head>

  <body ng-controller="niftyController" ng-app="niftyToast">
    <div class="container-fluid">
      <h2>AngularJS Nifty Toast Service</h2>
      <p>Toasts appened to the body, by element ID or by class name, configurable to auto timeout</p>
      <div class="row">
        <div class="col-sm-6">
          <form>
            <div class="form-group">
              <label for="message">Message:</label>
              <input ng-model="message" ng-init="message='test'" class="form-control" id="message" />
            </div>
            <div class="form-group">
              <label for="location">Location:</label>
              <input ng-model="location" class="form-control" placeholder="tag or id or class" ng-init="location='body'" id="location" />
            </div>
            <div class="form-group">
              <label for="placement">Place: </label>
              <div dropdown="" class="btn-group">
                <button id="placement" dropdown-toggle class="btn btn-default dropdown-toggle" type="button">
                  {{placement}} <span class="caret"></span>
                </button>
                <ul role="menu" class="dropdown-menu">
                  <li>
                    <a ng-click="placement='Append'" href="#">Append</a>
                  </li>
                  <li>
                    <a ng-click="placement='Prepend'" href="#">Prepend</a>
                  </li>
                </ul>
              </div>
              <label for="timer">&nbsp;Timer: </label>
              <div dropdown="" class="btn-group">
                <button id="timer" dropdown-toggle class="btn btn-default dropdown-toggle" type="button">
                  {{timer || 'None'}} <span class="caret"></span>
                </button>
                <ul role="menu" class="dropdown-menu">
                  <li>
                    <a ng-click="timer = null" href="#">None</a>
                  </li>
                  <li>
                    <a ng-click="timer = '1'" href="#">1 Seconds</a>
                  </li>
                <li>
                    <a ng-click="timer = '3'" href="#">3 Seconds</a>
                  </li>
                   <li>
                    <a ng-click="timer = '5'" href="#">5 Seconds</a>
                  </li>
                </ul>
              </div>
            </div>
            <div class="form-group text-center">
              <button ng-click="makeToast();" class="btn btn-primary">Toast It</button>
              <button ng-click="clearToast();" class="btn btn-warning">Clear Toasts</button>
            </div>
          </form>
        </div>
        <div class="col-sm-6">
          <ul>
            <li id="tango">test by ID #tango</li>
            <li class="omega" id="alpha">test by ID #alpha class .omega</li>
            <li class="special">test by class .special</li>
            <li class="omega gamma">test by class .omega .gamma</li>
            <li class="special">test by class</li>
          </ul>
        </div>
      </div>
    </div>
  </body>

</html>
angular.
 module('niftyToast', ['ui.bootstrap']).
 controller('niftyController', ['$scope', '$log', 'toast', function($scope, $log, toast) {
    $scope.location = null;
    $scope.message = null;
    $scope.placement = 'Prepend';
    $scope.timer = 3;
    
    $scope.makeToast = function(msg, options) {
      var toastOptions = {
        message: $scope.message,
        location: $scope.location,
        placement: $scope.placement,
        css: $scope.css,
        timer: $scope.timer
      }
      $log.debug('toasting', $scope.message, toastOptions);
      toast(toastOptions);
    };
    
    $scope.clearToast = function() {
      $log.debug('trying to clear toasts');
      toast('clearAll');
    };
  }]).
 factory('toast', ['$window', '$log', function(win, $log) {
    var id = 0;
    var toasts = {};
    var toast;
    var toastMessage;
    var toastOptions;
    
    var defaultPlacement = 'prepend';
    var defaultLocation = 'body';
    var defaultCSS = {
      top: '0px',
      bottom: '0px',
      width: '100%',
      background: 'blue',
      height: '30px',
      zIndex: '2'
    };
    
    /**
     * Remove all dom elements
     * Preconditions: element to remove
     * Postconditions: elements have been removed
     */
    function clearAll() {
      $log.debug(toasts);
      for (i = 0; i <= toasts.length; i++) {
        $log.debug(toasts[i]);
        clearElement(toasts[i]);
      }
      id = 0;
    }
    
    /**
     * Remove a single toast
     * Preconditions: toast element
     * Postconditions: toast has been removed
     */
    function clearElement(elem) {
        elem.domElem.remove();
        toasts[elem.id] = null;
    }
    
    function getElementsByIdentifier() {
      var location = null;
      var identifier = toast.location.substring(0, 1);
      var locationWithIdentifier = toast.location;
      var locationWithoutIdentifier = locationWithIdentifier.substring(1, locationWithIdentifier.length);

      switch (identifier)
      {
          case '#': //element id
              location = angular.element(document.getElementById(locationWithoutIdentifier)); break;
          case '.': //class
              location = angular.element(document.getElementsByClassName(locationWithoutIdentifier));
            break;
          default: //html tag
            location = angular.element(document).find(locationWithIdentifier);
      }
      
      return location;
    }
    
    function postToast() {
      var toastLocations = getElementsByIdentifier();

      angular.forEach(toastLocations, function(domElement) {
        createToast();
        var elem = angular.element(domElement);
        var toastMessage = createStyledDomElement();
        toast.domElem = toastMessage;

        if (toast.placement.toLowerCase() == 'append') {
          $log.debug('appending');
          elem.append(toastMessage);
        } else {
          $log.debug('prepending');
          elem.prepend(toastMessage);
        }
        
        toasts[toast.id] = toast;
      });
    }
    
    function setToastTimeout() {
      angular.forEach(toasts, function(elem) {
        $log.debug('setToastTimeout', elem);
        if (elem && elem.timer !== null && !elem.timeout) {
          elem.timeout = setTimeout(function(){
            clearTimeout(elem.timeout);
            clearElement(elem);
          }, elem.timer);
        }
      });
    }
    
    function createStyledDomElement() {
      return angular.element('<div>' + toast.message + '</div>').css(toast.css);
    }
    
    function createToast() {
      toast = {
        id: id++,
        domElem: null,
        timer: toastOptions.timer,
        css: angular.isDefined(toastOptions.css) ? toastOptions.css : defaultCSS,
        location: angular.isDefined(toastOptions.location) ? toastOptions.location : defaultLocation,
        placement: angular.isDefined(toastOptions.placement) ? toastOptions.placement : defaultPlacement,
        message: toastMessage,
        timeout: null
      };
      
      //make sure the timer is always in seconds
      if (toast.timer !== null && toast.timer < 1000) {
        toast.timer *= 1000;
      }
    }
    
    return function(options /*string or object*/) {
      
      if (!angular.isObject(options)){
        switch (options) {
          case 'clearAll':
          case 'clear': clearAll();
            break;
        }
      } else {
        toastMessage = options.message;
        toastOptions = options;
        createToast();
        postToast();
        setToastTimeout();
      }
    };
  }]);
http://jadendreamer.wordpress.com