angular-notify.js 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  1. angular.module('cgNotify', []).factory('notify',['$timeout','$http','$compile','$templateCache','$rootScope',
  2. function($timeout,$http,$compile,$templateCache,$rootScope){
  3. var startTop = 10;
  4. var verticalSpacing = 15;
  5. var defaultDuration = 10000;
  6. var defaultTemplateUrl = 'angular-notify.html';
  7. var position = 'center';
  8. var container = document.body;
  9. var maximumOpen = 0;
  10. var messageElements = [];
  11. var openNotificationsScope = [];
  12. var notify = function(args){
  13. if (typeof args !== 'object'){
  14. args = {message:args};
  15. }
  16. args.duration = args.duration ? args.duration : defaultDuration;
  17. args.templateUrl = args.templateUrl ? args.templateUrl : defaultTemplateUrl;
  18. args.container = args.container ? args.container : container;
  19. args.classes = args.classes ? args.classes : '';
  20. var scope = args.scope ? args.scope.$new() : $rootScope.$new();
  21. scope.$position = args.position ? args.position : position;
  22. scope.$message = args.message;
  23. scope.$classes = args.classes;
  24. scope.$messageTemplate = args.messageTemplate;
  25. if (maximumOpen > 0) {
  26. var numToClose = (openNotificationsScope.length + 1) - maximumOpen;
  27. for (var i = 0; i < numToClose; i++) {
  28. openNotificationsScope[i].$close();
  29. }
  30. }
  31. $http.get(args.templateUrl,{cache: $templateCache}).success(function(template){
  32. var templateElement = $compile(template)(scope);
  33. templateElement.bind('webkitTransitionEnd oTransitionEnd otransitionend transitionend msTransitionEnd', function(e){
  34. if (e.propertyName === 'opacity' || e.currentTarget.style.opacity === 0 ||
  35. (e.originalEvent && e.originalEvent.propertyName === 'opacity')){
  36. templateElement.remove();
  37. messageElements.splice(messageElements.indexOf(templateElement),1);
  38. openNotificationsScope.splice(openNotificationsScope.indexOf(scope),1);
  39. layoutMessages();
  40. }
  41. });
  42. if (args.messageTemplate){
  43. var messageTemplateElement;
  44. for (var i = 0; i < templateElement.children().length; i ++){
  45. if (angular.element(templateElement.children()[i]).hasClass('cg-notify-message-template')){
  46. messageTemplateElement = angular.element(templateElement.children()[i]);
  47. break;
  48. }
  49. }
  50. if (messageTemplateElement){
  51. messageTemplateElement.append($compile(args.messageTemplate)(scope));
  52. } else {
  53. throw new Error('cgNotify could not find the .cg-notify-message-template element in '+args.templateUrl+'.');
  54. }
  55. }
  56. angular.element(args.container).append(templateElement);
  57. messageElements.push(templateElement);
  58. if (scope.$position === 'center'){
  59. $timeout(function(){
  60. scope.$centerMargin = '-' + (templateElement[0].offsetWidth /2) + 'px';
  61. });
  62. }
  63. scope.$close = function(){
  64. templateElement.css('opacity',0).attr('data-closing','true');
  65. layoutMessages();
  66. };
  67. var layoutMessages = function(){
  68. var j = 0;
  69. var currentY = startTop;
  70. for(var i = messageElements.length - 1; i >= 0; i --){
  71. var shadowHeight = 10;
  72. var element = messageElements[i];
  73. var height = element[0].offsetHeight;
  74. var top = currentY + height + shadowHeight;
  75. if (element.attr('data-closing')){
  76. top += 20;
  77. } else {
  78. currentY += height + verticalSpacing;
  79. }
  80. element.css('top',top + 'px').css('margin-top','-' + (height+shadowHeight) + 'px').css('visibility','visible');
  81. j ++;
  82. }
  83. };
  84. $timeout(function(){
  85. layoutMessages();
  86. });
  87. if (args.duration > 0){
  88. $timeout(function(){
  89. scope.$close();
  90. },args.duration);
  91. }
  92. }).error(function(data){
  93. throw new Error('Template specified for cgNotify ('+args.templateUrl+') could not be loaded. ' + data);
  94. });
  95. var retVal = {};
  96. retVal.close = function(){
  97. if (scope.$close){
  98. scope.$close();
  99. }
  100. };
  101. Object.defineProperty(retVal,'message',{
  102. get: function(){
  103. return scope.$message;
  104. },
  105. set: function(val){
  106. scope.$message = val;
  107. }
  108. });
  109. openNotificationsScope.push(scope);
  110. return retVal;
  111. };
  112. notify.config = function(args){
  113. startTop = !angular.isUndefined(args.startTop) ? args.startTop : startTop;
  114. verticalSpacing = !angular.isUndefined(args.verticalSpacing) ? args.verticalSpacing : verticalSpacing;
  115. defaultDuration = !angular.isUndefined(args.duration) ? args.duration : defaultDuration;
  116. defaultTemplateUrl = args.templateUrl ? args.templateUrl : defaultTemplateUrl;
  117. position = !angular.isUndefined(args.position) ? args.position : position;
  118. container = args.container ? args.container : container;
  119. maximumOpen = args.maximumOpen ? args.maximumOpen : maximumOpen;
  120. };
  121. notify.closeAll = function(){
  122. for(var i = messageElements.length - 1; i >= 0; i --){
  123. var element = messageElements[i];
  124. element.css('opacity',0);
  125. }
  126. };
  127. return notify;
  128. }
  129. ]);