Subversion Repositories Integrator Subversion

Rev

Details | Last modification | View Log | RSS feed

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