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