jquery.toast.js 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374
  1. // jQuery toast plugin created by Kamran Ahmed copyright MIT license 2015
  2. if ( typeof Object.create !== 'function' ) {
  3. Object.create = function( obj ) {
  4. function F() {}
  5. F.prototype = obj;
  6. return new F();
  7. };
  8. }
  9. (function( $, window, document, undefined ) {
  10. "use strict";
  11. var Toast = {
  12. _positionClasses : ['bottom-left', 'bottom-right', 'top-right', 'top-left', 'bottom-center', 'top-center', 'mid-center'],
  13. _defaultIcons : ['success', 'error', 'info', 'warning'],
  14. init: function (options, elem) {
  15. this.prepareOptions(options, $.toast.options);
  16. this.process();
  17. },
  18. prepareOptions: function(options, options_to_extend) {
  19. var _options = {};
  20. if ( ( typeof options === 'string' ) || ( options instanceof Array ) ) {
  21. _options.text = options;
  22. } else {
  23. _options = options;
  24. }
  25. this.options = $.extend( {}, options_to_extend, _options );
  26. },
  27. process: function () {
  28. this.setup();
  29. this.addToDom();
  30. this.position();
  31. this.bindToast();
  32. this.animate();
  33. },
  34. setup: function () {
  35. var _toastContent = '';
  36. this._toastEl = this._toastEl || $('<div></div>', {
  37. class : 'jq-toast-single'
  38. });
  39. // For the loader on top
  40. _toastContent += '<span class="jq-toast-loader"></span>';
  41. if ( this.options.allowToastClose ) {
  42. _toastContent += '<span class="close-jq-toast-single">&times;</span>';
  43. };
  44. if ( this.options.text instanceof Array ) {
  45. if ( this.options.heading ) {
  46. _toastContent +='<h2 class="jq-toast-heading">' + this.options.heading + '</h2>';
  47. };
  48. _toastContent += '<ul class="jq-toast-ul">';
  49. for (var i = 0; i < this.options.text.length; i++) {
  50. _toastContent += '<li class="jq-toast-li" id="jq-toast-item-' + i + '">' + this.options.text[i] + '</li>';
  51. }
  52. _toastContent += '</ul>';
  53. } else {
  54. if ( this.options.heading ) {
  55. _toastContent +='<h2 class="jq-toast-heading">' + this.options.heading + '</h2>';
  56. };
  57. _toastContent += this.options.text;
  58. }
  59. this._toastEl.html( _toastContent );
  60. if ( this.options.bgColor !== false ) {
  61. this._toastEl.css("background-color", this.options.bgColor);
  62. };
  63. if ( this.options.textColor !== false ) {
  64. this._toastEl.css("color", this.options.textColor);
  65. };
  66. if ( this.options.textAlign ) {
  67. this._toastEl.css('text-align', this.options.textAlign);
  68. }
  69. if ( this.options.icon !== false ) {
  70. this._toastEl.addClass('jq-has-icon');
  71. if ( $.inArray(this.options.icon, this._defaultIcons) !== -1 ) {
  72. this._toastEl.addClass('jq-icon-' + this.options.icon);
  73. };
  74. };
  75. if ( this.options.class !== false ){
  76. this._toastEl.addClass(this.options.class)
  77. }
  78. },
  79. position: function () {
  80. if ( ( typeof this.options.position === 'string' ) && ( $.inArray( this.options.position, this._positionClasses) !== -1 ) ) {
  81. if ( this.options.position === 'bottom-center' ) {
  82. this._container.css({
  83. left: ( $(window).outerWidth() / 2 ) - this._container.outerWidth()/2,
  84. bottom: 20
  85. });
  86. } else if ( this.options.position === 'top-center' ) {
  87. this._container.css({
  88. left: ( $(window).outerWidth() / 2 ) - this._container.outerWidth()/2,
  89. top: 20
  90. });
  91. } else if ( this.options.position === 'mid-center' ) {
  92. this._container.css({
  93. left: ( $(window).outerWidth() / 2 ) - this._container.outerWidth()/2,
  94. top: ( $(window).outerHeight() / 2 ) - this._container.outerHeight()/2
  95. });
  96. } else {
  97. this._container.addClass( this.options.position );
  98. }
  99. } else if ( typeof this.options.position === 'object' ) {
  100. this._container.css({
  101. top : this.options.position.top ? this.options.position.top : 'auto',
  102. bottom : this.options.position.bottom ? this.options.position.bottom : 'auto',
  103. left : this.options.position.left ? this.options.position.left : 'auto',
  104. right : this.options.position.right ? this.options.position.right : 'auto'
  105. });
  106. } else {
  107. this._container.addClass( 'bottom-left' );
  108. }
  109. },
  110. bindToast: function () {
  111. var that = this;
  112. this._toastEl.on('afterShown', function () {
  113. that.processLoader();
  114. });
  115. this._toastEl.find('.close-jq-toast-single').on('click', function ( e ) {
  116. e.preventDefault();
  117. if( that.options.showHideTransition === 'fade') {
  118. that._toastEl.trigger('beforeHide');
  119. that._toastEl.fadeOut(function () {
  120. that._toastEl.trigger('afterHidden');
  121. });
  122. } else if ( that.options.showHideTransition === 'slide' ) {
  123. that._toastEl.trigger('beforeHide');
  124. that._toastEl.slideUp(function () {
  125. that._toastEl.trigger('afterHidden');
  126. });
  127. } else {
  128. that._toastEl.trigger('beforeHide');
  129. that._toastEl.hide(function () {
  130. that._toastEl.trigger('afterHidden');
  131. });
  132. }
  133. });
  134. if ( typeof this.options.beforeShow == 'function' ) {
  135. this._toastEl.on('beforeShow', function () {
  136. that.options.beforeShow(that._toastEl);
  137. });
  138. };
  139. if ( typeof this.options.afterShown == 'function' ) {
  140. this._toastEl.on('afterShown', function () {
  141. that.options.afterShown(that._toastEl);
  142. });
  143. };
  144. if ( typeof this.options.beforeHide == 'function' ) {
  145. this._toastEl.on('beforeHide', function () {
  146. that.options.beforeHide(that._toastEl);
  147. });
  148. };
  149. if ( typeof this.options.afterHidden == 'function' ) {
  150. this._toastEl.on('afterHidden', function () {
  151. that.options.afterHidden(that._toastEl);
  152. });
  153. };
  154. if ( typeof this.options.onClick == 'function' ) {
  155. this._toastEl.on('click', function () {
  156. that.options.onClick(that._toastEl);
  157. });
  158. };
  159. },
  160. addToDom: function () {
  161. var _container = $('.jq-toast-wrap');
  162. if ( _container.length === 0 ) {
  163. _container = $('<div></div>',{
  164. class: "jq-toast-wrap",
  165. role: "alert",
  166. "aria-live": "polite"
  167. });
  168. $('body').append( _container );
  169. } else if ( !this.options.stack || isNaN( parseInt(this.options.stack, 10) ) ) {
  170. _container.empty();
  171. }
  172. _container.find('.jq-toast-single:hidden').remove();
  173. _container.append( this._toastEl );
  174. if ( this.options.stack && !isNaN( parseInt( this.options.stack ), 10 ) ) {
  175. var _prevToastCount = _container.find('.jq-toast-single').length,
  176. _extToastCount = _prevToastCount - this.options.stack;
  177. if ( _extToastCount > 0 ) {
  178. $('.jq-toast-wrap').find('.jq-toast-single').slice(0, _extToastCount).remove();
  179. };
  180. }
  181. this._container = _container;
  182. },
  183. canAutoHide: function () {
  184. return ( this.options.hideAfter !== false ) && !isNaN( parseInt( this.options.hideAfter, 10 ) );
  185. },
  186. processLoader: function () {
  187. // Show the loader only, if auto-hide is on and loader is demanded
  188. if (!this.canAutoHide() || this.options.loader === false) {
  189. return false;
  190. }
  191. var loader = this._toastEl.find('.jq-toast-loader');
  192. // 400 is the default time that jquery uses for fade/slide
  193. // Divide by 1000 for milliseconds to seconds conversion
  194. var transitionTime = (this.options.hideAfter - 400) / 1000 + 's';
  195. var loaderBg = this.options.loaderBg;
  196. var style = loader.attr('style') || '';
  197. style = style.substring(0, style.indexOf('-webkit-transition')); // Remove the last transition definition
  198. style += '-webkit-transition: width ' + transitionTime + ' ease-in; \
  199. -o-transition: width ' + transitionTime + ' ease-in; \
  200. transition: width ' + transitionTime + ' ease-in; \
  201. background-color: ' + loaderBg + ';';
  202. loader.attr('style', style).addClass('jq-toast-loaded');
  203. },
  204. animate: function () {
  205. var that = this;
  206. this._toastEl.hide();
  207. this._toastEl.trigger('beforeShow');
  208. if ( this.options.showHideTransition.toLowerCase() === 'fade' ) {
  209. this._toastEl.fadeIn(function ( ){
  210. that._toastEl.trigger('afterShown');
  211. });
  212. } else if ( this.options.showHideTransition.toLowerCase() === 'slide' ) {
  213. this._toastEl.slideDown(function ( ){
  214. that._toastEl.trigger('afterShown');
  215. });
  216. } else {
  217. this._toastEl.show(function ( ){
  218. that._toastEl.trigger('afterShown');
  219. });
  220. }
  221. if (this.canAutoHide()) {
  222. var that = this;
  223. window.setTimeout(function(){
  224. if ( that.options.showHideTransition.toLowerCase() === 'fade' ) {
  225. that._toastEl.trigger('beforeHide');
  226. that._toastEl.fadeOut(function () {
  227. that._toastEl.trigger('afterHidden');
  228. });
  229. } else if ( that.options.showHideTransition.toLowerCase() === 'slide' ) {
  230. that._toastEl.trigger('beforeHide');
  231. that._toastEl.slideUp(function () {
  232. that._toastEl.trigger('afterHidden');
  233. });
  234. } else {
  235. that._toastEl.trigger('beforeHide');
  236. that._toastEl.hide(function () {
  237. that._toastEl.trigger('afterHidden');
  238. });
  239. }
  240. }, this.options.hideAfter);
  241. };
  242. },
  243. reset: function ( resetWhat ) {
  244. if ( resetWhat === 'all' ) {
  245. $('.jq-toast-wrap').remove();
  246. } else {
  247. this._toastEl.remove();
  248. }
  249. },
  250. update: function(options) {
  251. this.prepareOptions(options, this.options);
  252. this.setup();
  253. this.bindToast();
  254. },
  255. close: function() {
  256. this._toastEl.find('.close-jq-toast-single').click();
  257. }
  258. };
  259. $.toast = function(options) {
  260. var toast = Object.create(Toast);
  261. toast.init(options, this);
  262. return {
  263. reset: function ( what ) {
  264. toast.reset( what );
  265. },
  266. update: function( options ) {
  267. toast.update( options );
  268. },
  269. close: function( ) {
  270. toast.close( );
  271. }
  272. }
  273. };
  274. $.toast.options = {
  275. text: '',
  276. heading: '',
  277. showHideTransition: 'fade',
  278. allowToastClose: true,
  279. hideAfter: 3000,
  280. loader: true,
  281. loaderBg: '#9EC600',
  282. stack: 5,
  283. position: 'bottom-left',
  284. bgColor: false,
  285. textColor: false,
  286. textAlign: 'left',
  287. icon: false,
  288. beforeShow: function () {},
  289. afterShown: function () {},
  290. beforeHide: function () {},
  291. afterHidden: function () {},
  292. onClick: function () {}
  293. };
  294. })( jQuery, window, document );