You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

256 regels
7.5 KiB

  1. /*!
  2. * Bootstrap Confirmation
  3. * Copyright 2013 Nimit Suwannagate <ethaizone@hotmail.com>
  4. * Copyright 2014-2016 Damien "Mistic" Sorel <http://www.strangeplanet.fr>
  5. * Licensed under the Apache License, Version 2.0 (the "License")
  6. */
  7. (function ($) {
  8. 'use strict';
  9. // Confirmation extends popover.js
  10. if (!$.fn.popover) throw new Error('Confirmation requires popover.js');
  11. // CONFIRMATION PUBLIC CLASS DEFINITION
  12. // ===============================
  13. var Confirmation = function (element, options) {
  14. options.trigger = 'click';
  15. this.init('confirmation', element, options);
  16. // keep trace of selectors
  17. this.options._isDelegate = false;
  18. if (options.selector) { // container of buttons
  19. this.options._selector = this._options._selector = options._root_selector +' '+ options.selector;
  20. }
  21. else if (options._selector) { // children of container
  22. this.options._selector = options._selector;
  23. this.options._isDelegate = true;
  24. }
  25. else { // standalone
  26. this.options._selector = options._root_selector;
  27. }
  28. var that = this;
  29. if (!this.options.selector) {
  30. // store copied attributes
  31. this.options._attributes = {};
  32. if (this.options.copyAttributes) {
  33. if (typeof this.options.copyAttributes === 'string') {
  34. this.options.copyAttributes = this.options.copyAttributes.split(' ');
  35. }
  36. }
  37. else {
  38. this.options.copyAttributes = [];
  39. }
  40. this.options.copyAttributes.forEach(function(attr) {
  41. this.options._attributes[attr] = this.$element.attr(attr);
  42. }, this);
  43. // cancel original event
  44. this.$element.on(that.options.trigger, function(e, ack) {
  45. if (!ack) {
  46. e.preventDefault();
  47. e.stopPropagation();
  48. e.stopImmediatePropagation();
  49. }
  50. });
  51. // manage singleton
  52. this.$element.on('show.bs.confirmation', function(e) {
  53. if (that.options.singleton) {
  54. // close all other popover already initialized
  55. $(that.options._selector).not($(this)).filter(function() {
  56. return $(this).data('bs.confirmation') !== undefined;
  57. }).confirmation('hide');
  58. }
  59. });
  60. }
  61. if (!this.options._isDelegate) {
  62. // manage popout
  63. this.eventBody = false;
  64. this.uid = this.$element[0].id || this.getUID('group_');
  65. this.$element.on('shown.bs.confirmation', function(e) {
  66. if (that.options.popout && !that.eventBody) {
  67. var $this = $(this);
  68. that.eventBody = $('body').on('click.bs.confirmation.'+that.uid, function(e) {
  69. if ($(that.options._selector).is(e.target)) {
  70. return;
  71. }
  72. // close all popover already initialized
  73. $(that.options._selector).filter(function() {
  74. return $(this).data('bs.confirmation') !== undefined;
  75. }).confirmation('hide');
  76. $('body').off('click.bs.'+that.uid);
  77. that.eventBody = false;
  78. });
  79. }
  80. });
  81. }
  82. };
  83. Confirmation.DEFAULTS = $.extend({}, $.fn.popover.Constructor.DEFAULTS, {
  84. placement: 'top',
  85. title: 'Are you sure?',
  86. html: true,
  87. popout: false,
  88. singleton: false,
  89. copyAttributes: 'href target',
  90. onConfirm: $.noop,
  91. onCancel: $.noop,
  92. btnOkClass: 'btn-xs btn-primary',
  93. btnOkIcon: 'glyphicon glyphicon-ok',
  94. btnOkLabel: 'Yes',
  95. btnCancelClass: 'btn-xs btn-default',
  96. btnCancelIcon: 'glyphicon glyphicon-remove',
  97. btnCancelLabel: 'No',
  98. template:
  99. '<div class="popover confirmation">' +
  100. '<div class="arrow"></div>' +
  101. '<h3 class="popover-title"></h3>' +
  102. '<div class="popover-content text-center">'+
  103. '<div class="btn-group">'+
  104. '<a class="btn" data-apply="confirmation"></a>'+
  105. '<a class="btn" data-dismiss="confirmation"></a>'+
  106. '</div>'+
  107. '</div>'+
  108. '</div>'
  109. });
  110. Confirmation.prototype = $.extend({}, $.fn.popover.Constructor.prototype);
  111. Confirmation.prototype.constructor = Confirmation;
  112. Confirmation.prototype.getDefaults = function () {
  113. return Confirmation.DEFAULTS;
  114. };
  115. Confirmation.prototype.setContent = function () {
  116. var that = this,
  117. $tip = this.tip(),
  118. o = this.options;
  119. $tip.find('.popover-title')[o.html ? 'html' : 'text'](this.getTitle());
  120. // configure 'ok' button
  121. $tip.find('[data-apply="confirmation"]')
  122. .addClass(o.btnOkClass)
  123. .html(o.btnOkLabel)
  124. .attr(this.options._attributes)
  125. .prepend($('<i></i>').addClass(o.btnOkIcon), ' ')
  126. .off('click')
  127. .one('click', function(e) {
  128. that.getOnConfirm.call(that).call(that.$element);
  129. that.$element.trigger('confirmed.bs.confirmation');
  130. that.$element.trigger(that.options.trigger, [true]);
  131. that.$element.confirmation('hide');
  132. });
  133. // configure 'cancel' button
  134. $tip.find('[data-dismiss="confirmation"]')
  135. .addClass(o.btnCancelClass)
  136. .html(o.btnCancelLabel)
  137. .prepend($('<i></i>').addClass(o.btnCancelIcon), ' ')
  138. .off('click')
  139. .one('click', function(e) {
  140. that.getOnCancel.call(that).call(that.$element);
  141. if (that.inState) that.inState.click = false; // Bootstrap 3.3.5
  142. that.$element.trigger('canceled.bs.confirmation');
  143. that.$element.confirmation('hide');
  144. });
  145. $tip.removeClass('fade top bottom left right in');
  146. // IE8 doesn't accept hiding via the `:empty` pseudo selector, we have to do
  147. // this manually by checking the contents.
  148. if (!$tip.find('.popover-title').html()) {
  149. $tip.find('.popover-title').hide();
  150. }
  151. };
  152. Confirmation.prototype.getOnConfirm = function() {
  153. if (this.$element.attr('data-on-confirm')) {
  154. return getFunctionFromString(this.$element.attr('data-on-confirm'));
  155. }
  156. else {
  157. return this.options.onConfirm;
  158. }
  159. };
  160. Confirmation.prototype.getOnCancel = function() {
  161. if (this.$element.attr('data-on-cancel')) {
  162. return getFunctionFromString(this.$element.attr('data-on-cancel'));
  163. }
  164. else {
  165. return this.options.onCancel;
  166. }
  167. };
  168. /*
  169. * Generates an anonymous function from a function name
  170. * function name may contain dots (.) to navigate through objects
  171. * root context is window
  172. */
  173. function getFunctionFromString(functionName) {
  174. var context = window,
  175. namespaces = functionName.split('.'),
  176. func = namespaces.pop();
  177. for (var i=0, l=namespaces.length; i<l; i++) {
  178. context = context[namespaces[i]];
  179. }
  180. return function() {
  181. context[func].call(this);
  182. };
  183. }
  184. // CONFIRMATION PLUGIN DEFINITION
  185. // =========================
  186. var old = $.fn.confirmation;
  187. $.fn.confirmation = function (option) {
  188. var options = (typeof option == 'object' && option) || {};
  189. options._root_selector = this.selector;
  190. return this.each(function () {
  191. var $this = $(this),
  192. data = $this.data('bs.confirmation');
  193. if (!data && option == 'destroy') {
  194. return;
  195. }
  196. if (!data) {
  197. $this.data('bs.confirmation', (data = new Confirmation(this, options)));
  198. }
  199. if (typeof option == 'string') {
  200. data[option]();
  201. if (option == 'hide' && data.inState) { //data.inState doesn't exist in Bootstrap < 3.3.5
  202. data.inState.click = false;
  203. }
  204. }
  205. });
  206. };
  207. $.fn.confirmation.Constructor = Confirmation;
  208. // CONFIRMATION NO CONFLICT
  209. // ===================
  210. $.fn.confirmation.noConflict = function () {
  211. $.fn.confirmation = old;
  212. return this;
  213. };
  214. }(jQuery));