jquery-confirm.js 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438
  1. /*!
  2. * jquery-confirm v1.7.5 (http://craftpip.github.io/jquery-confirm/)
  3. * Author: Boniface Pereira
  4. * Website: www.craftpip.com
  5. * Contact: hey@craftpip.com
  6. *
  7. * Copyright 2013-2015 jquery-confirm
  8. * Licensed under MIT (https://github.com/craftpip/jquery-confirm/blob/master/LICENSE)
  9. */
  10. if (typeof jQuery === 'undefined') {
  11. throw new Error('jquery-confirm requires jQuery');
  12. }
  13. var jconfirm, Jconfirm;
  14. (function ($) {
  15. "use strict";
  16. $.confirm = function (options) {
  17. /*
  18. * Alias of jconfirm
  19. */
  20. return jconfirm(options);
  21. };
  22. $.alert = function (options) {
  23. /*
  24. * Alias of jconfirm
  25. */
  26. options.cancelButton = false;
  27. return jconfirm(options);
  28. };
  29. $.dialog = function (options) {
  30. /*
  31. * Alias of jconfirm
  32. */
  33. options.cancelButton = false;
  34. options.confirmButton = false;
  35. return jconfirm(options);
  36. };
  37. jconfirm = function (options) {
  38. /*
  39. * initial function for calling.
  40. */
  41. if (jconfirm.defaults) {
  42. /*
  43. * Merge global defaults with plugin defaults
  44. */
  45. $.extend(jconfirm.pluginDefaults, jconfirm.defaults);
  46. }
  47. /*
  48. * merge options with plugin defaults.
  49. */
  50. var options = $.extend({}, jconfirm.pluginDefaults, options);
  51. return new Jconfirm(options);
  52. };
  53. Jconfirm = function (options) {
  54. /*
  55. * constructor function Jconfirm,
  56. * options = user options.
  57. */
  58. $.extend(this, options);
  59. this._init();
  60. };
  61. Jconfirm.prototype = {
  62. _init: function () {
  63. var that = this;
  64. this._rand = Math.round(Math.random() * 99999);
  65. this._buildHTML();
  66. this._bindEvents();
  67. setTimeout(function () {
  68. that.open();
  69. }, 0);
  70. },
  71. animations: ['anim-scale', 'anim-top', 'anim-bottom', 'anim-left', 'anim-right', 'anim-zoom', 'anim-opacity', 'anim-none', 'anim-rotate', 'anim-rotatex', 'anim-rotatey', 'anim-scalex', 'anim-scaley'],
  72. _buildHTML: function () {
  73. var that = this;
  74. /*
  75. * Cleaning animations.
  76. */
  77. this.animation = 'anim-' + this.animation.toLowerCase();
  78. if (this.animation === 'none')
  79. this.animationSpeed = 0;
  80. /*
  81. * Append html to body.
  82. */
  83. this.$el = $(this.template).appendTo(this.container).addClass(this.theme);
  84. this.$el.find('.jconfirm-box-container').addClass(this.columnClass);
  85. this.CSS = {
  86. '-webkit-transition-duration': this.animationSpeed / 1000 + 's',
  87. 'transition-duration': this.animationSpeed / 1000 + 's',
  88. '-webkjit-transition-timing-function': 'cubic-bezier(0.27, 1.12, 0.32, ' + this.animationBounce + ')',
  89. 'transition-timing-function': 'cubic-bezier(0.27, 1.12, 0.32, ' + this.animationBounce + ')',
  90. };
  91. this.$el.find('.jconfirm-bg').css(this.CSS);
  92. this.$b = this.$el.find('.jconfirm-box').css(this.CSS).addClass(this.animation);
  93. /*
  94. * Setup title contents
  95. */
  96. this.setTitle();
  97. this.contentDiv = this.$el.find('div.content');
  98. /*
  99. * Settings up buttons
  100. */
  101. this.$btnc = this.$el.find('.buttons');
  102. if (this.confirmButton && this.confirmButton.trim() !== '') {
  103. this.$confirmButton = $('<button class="btn">' + this.confirmButton + '</button>')
  104. .appendTo(this.$btnc)
  105. .addClass(this.confirmButtonClass);
  106. }
  107. if (this.cancelButton && this.cancelButton.trim() !== '') {
  108. this.$cancelButton = $('<button class="btn">' + this.cancelButton + '</button>')
  109. .appendTo(this.$btnc)
  110. .addClass(this.cancelButtonClass);
  111. }
  112. if (!this.confirmButton && !this.cancelButton) {
  113. this.$btnc.remove();
  114. }
  115. if(!this.confirmButton && !this.cancelButton && this.closeIcon == null){
  116. this.$closeButton = this.$b.find('.closeIcon').show();
  117. }
  118. if (this.closeIcon === true){
  119. this.$closeButton = this.$b.find('.closeIcon').show();
  120. }
  121. this.setContent();
  122. if (this.autoClose)
  123. this._startCountDown();
  124. },
  125. setTitle: function(string){
  126. this.title = (typeof string !== 'undefined') ? string : this.title;
  127. if (this.title) {
  128. this.$el.find('div.title').html('<i class="' + this.icon + '"></i> ' + this.title);
  129. } else {
  130. this.$el.find('div.title').remove();
  131. }
  132. },
  133. setContent: function (string) {
  134. var that = this;
  135. this.content = (string) ? string : this.content;
  136. var animate = (string) ? true : false;
  137. /*
  138. * Set content.
  139. */
  140. if (typeof this.content === 'boolean') {
  141. if (!this.content)
  142. this.contentDiv.remove();
  143. else
  144. console.error('Invalid option for property content: passed TRUE');
  145. } else if (typeof this.content === 'string') {
  146. if (this.content.substr(0, 4).toLowerCase() === 'url:') {
  147. this.contentDiv.html('');
  148. this.$btnc.find('button').prop('disabled', true);
  149. var url = this.content.substring(4, this.content.length);
  150. $.get(url).done(function (html) {
  151. that.contentDiv.html(html);
  152. }).always(function (data, status, xhr) {
  153. if (typeof that.contentLoaded === 'function')
  154. that.contentLoaded(data, status, xhr);
  155. that.$btnc.find('button').prop('disabled', false);
  156. that.setDialogCenter();
  157. });
  158. } else {
  159. this.contentDiv.html(this.content);
  160. }
  161. } else if (typeof this.content === 'function') {
  162. this.contentDiv.html('');
  163. this.$btnc.find('button').attr('disabled', 'disabled');
  164. var promise = this.content(this);
  165. if (typeof promise !== 'object') {
  166. console.error('The content function must return jquery promise.');
  167. } else if (typeof promise.always !== 'function') {
  168. console.error('The object returned is not a jquery promise.');
  169. } else {
  170. promise.always(function (data, status) {
  171. that.$btnc.find('button').removeAttr('disabled');
  172. that.setDialogCenter();
  173. });
  174. }
  175. } else {
  176. console.error('Invalid option for property content, passed: ' + typeof this.content);
  177. }
  178. this.setDialogCenter(animate);
  179. },
  180. _startCountDown: function () {
  181. var opt = this.autoClose.split('|');
  182. if (/cancel/.test(opt[0]) && this.type === 'alert') {
  183. return false;
  184. } else if (/confirm|cancel/.test(opt[0])) {
  185. this.$cd = $('<span class="countdown">').appendTo(this['$' + opt[0] + 'Button']);
  186. var that = this;
  187. that.$cd.parent().click();
  188. var time = opt[1] / 1000;
  189. this.interval = setInterval(function () {
  190. that.$cd.html(' [' + (time -= 1) + ']');
  191. if (time === 0) {
  192. that.$cd.parent().trigger('click');
  193. clearInterval(that.interval);
  194. }
  195. }, 1000);
  196. } else {
  197. console.error('Invalid option ' + opt[0] + ', must be confirm/cancel');
  198. }
  199. },
  200. _bindEvents: function () {
  201. var that = this;
  202. this.$el.find('.jconfirm-scrollpane').click(function (e) {
  203. if (that.backgroundDismiss) {
  204. that.cancel();
  205. that.close();
  206. } else {
  207. that.$b.addClass('hilight');
  208. setTimeout(function () {
  209. that.$b.removeClass('hilight');
  210. }, 400);
  211. }
  212. });
  213. this.$el.find('.jconfirm-box').click(function (e) {
  214. e.stopPropagation();
  215. });
  216. if (this.$confirmButton) {
  217. this.$confirmButton.click(function (e) {
  218. e.preventDefault();
  219. var r = that.confirm(that.$b);
  220. that.onAction();
  221. if (typeof r === 'undefined' || r)
  222. that.close();
  223. });
  224. }
  225. if (this.$cancelButton) {
  226. this.$cancelButton.click(function (e) {
  227. e.preventDefault();
  228. var r = that.cancel(that.$b);
  229. that.onAction();
  230. if (typeof r === 'undefined' || r)
  231. that.close();
  232. });
  233. }
  234. if (this.$closeButton) {
  235. this.$closeButton.click(function (e) {
  236. e.preventDefault();
  237. that.cancel();
  238. that.onAction();
  239. that.close();
  240. });
  241. }
  242. if (this.keyboardEnabled) {
  243. setTimeout(function () {
  244. $(window).on('keyup.' + this._rand, function (e) {
  245. that.reactOnKey(e);
  246. });
  247. }, 500);
  248. }
  249. $(window).on('resize.' + this._rand, function () {
  250. that.setDialogCenter(true);
  251. });
  252. },
  253. reactOnKey: function key(e) {
  254. /*
  255. * prevent keyup event if the dialog is not last!
  256. */
  257. var a = $('.jconfirm');
  258. if (a.eq(a.length - 1)[0] !== this.$el[0])
  259. return false;
  260. var key = e.which;
  261. if (key === 27) {
  262. /*
  263. * if ESC key
  264. */
  265. if (!this.backgroundDismiss) {
  266. /*
  267. * If background dismiss is false, Glow the modal.
  268. */
  269. this.$el.find('.jconfirm-bg').click();
  270. return false;
  271. }
  272. if (this.$cancelButton) {
  273. this.$cancelButton.click();
  274. } else {
  275. this.close();
  276. }
  277. }
  278. if (key === 13 || key == 32) {
  279. /*
  280. * if ENTER or SPACE key
  281. */
  282. if (this.$confirmButton) {
  283. this.$confirmButton.click();
  284. } else {
  285. }
  286. }
  287. },
  288. setDialogCenter: function (animate) {
  289. var windowHeight = $(window).height();
  290. var boxHeight = this.$b.outerHeight();
  291. var topMargin = (windowHeight - boxHeight) / 2;
  292. var minMargin = 100;
  293. if (boxHeight > (windowHeight - minMargin)) {
  294. var style = {
  295. 'margin-top': minMargin / 2,
  296. 'margin-bottom': minMargin / 2,
  297. }
  298. } else {
  299. var style = {
  300. 'margin-top': topMargin,
  301. }
  302. }
  303. if (animate) {
  304. this.$b.animate(style, {
  305. duration: this.animationSpeed,
  306. queue: false
  307. });
  308. } else {
  309. this.$b.css(style);
  310. }
  311. },
  312. close: function () {
  313. var that = this;
  314. if(this.isClosed())
  315. return false;
  316. if(typeof this.onClose === 'function')
  317. this.onClose();
  318. /*
  319. unbind the window resize & keyup event.
  320. */
  321. $(window).unbind('resize.' + this._rand);
  322. if (this.keyboardEnabled)
  323. $(window).unbind('keyup.' + this._rand);
  324. that.$el.find('.jconfirm-bg').removeClass('seen');
  325. this.$b.addClass(this.animation);
  326. setTimeout(function () {
  327. that.$el.remove();
  328. }, this.animationSpeed + 10); // wait 10 miliseconds more, ensure everything is done.
  329. jconfirm.record.closed += 1;
  330. jconfirm.record.currentlyOpen -= 1;
  331. if(jconfirm.record.currentlyOpen < 1)
  332. $('body').removeClass('jconfirm-noscroll');
  333. return true;
  334. },
  335. open: function () {
  336. var that = this;
  337. if (this.isClosed())
  338. return false;
  339. that.$el.find('.jconfirm-bg').addClass('seen');
  340. $('body').addClass('jconfirm-noscroll');
  341. this.$b.removeClass(this.animations.join(' '));
  342. /**
  343. * Blur the focused elements, prevents re-execution with button press.
  344. */
  345. $('body :focus').trigger('blur');
  346. this.$b.find('input[autofocus]:visible:first').focus();
  347. jconfirm.record.opened += 1;
  348. jconfirm.record.currentlyOpen += 1;
  349. if(typeof this.onOpen === 'function')
  350. this.onOpen();
  351. return true;
  352. },
  353. isClosed: function () {
  354. return (this.$el.css('display') === '') ? true : false;
  355. }
  356. };
  357. jconfirm.pluginDefaults = {
  358. template: '<div class="jconfirm"><div class="jconfirm-bg"></div><div class="jconfirm-scrollpane"><div class="container"><div class="row"><div class="jconfirm-box-container span6 offset3"><div class="jconfirm-box"><div class="closeIcon"><span class="glyphicon glyphicon-remove"></span></div><div class="title"></div><div class="content"></div><div class="buttons"></div><div class="jquery-clear"></div></div></div></div></div></div></div>',
  359. title: 'Hello',
  360. content: 'Are you sure to continue?',
  361. contentLoaded: function () {
  362. },
  363. icon: '',
  364. confirmButton: '确定',
  365. cancelButton: '取消',
  366. confirmButtonClass: 'btn-default',
  367. cancelButtonClass: 'btn-default',
  368. theme: 'white',
  369. animation: 'scale',
  370. animationSpeed: 400,
  371. animationBounce: 1.5,
  372. keyboardEnabled: false,
  373. container: 'body',
  374. confirm: function () {
  375. },
  376. cancel: function () {
  377. },
  378. backgroundDismiss: true,
  379. autoClose: false,
  380. closeIcon: null,
  381. columnClass: 'col-md-6 col-md-offset-3',
  382. onOpen: function(){
  383. },
  384. onClose: function(){
  385. },
  386. onAction: function(){
  387. }
  388. };
  389. jconfirm.record = {
  390. opened: 0,
  391. closed: 0,
  392. currentlyOpen: 0,
  393. };
  394. })(jQuery);