bootstrap5-toggle 5.0.5 → 5.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,464 +1,491 @@
1
- /* Copyright Notice
2
- * bootstrap5-toggle v5.0.5
3
- * https://palcarazm.github.io/bootstrap5-toggle/
4
- * @author 2011-2014 Min Hur (https://github.com/minhur)
5
- * @author 2018-2019 Brent Ely (https://github.com/gitbrent)
6
- * @author 2022 Pablo Alcaraz Martínez (https://github.com/palcarazm)
7
- * @funding GitHub Sponsors
8
- * @see https://github.com/sponsors/palcarazm
9
- * @license MIT
10
- * @see https://github.com/palcarazm/bootstrap5-toggle/blob/master/LICENSE
11
- */
12
-
13
-
14
- +(function ($) {
15
- "use strict";
16
-
17
- // TOGGLE PUBLIC CLASS DEFINITION
18
- // ==============================
19
-
20
- let Toggle = function (element, options) {
21
- // A: Capture ref to HMTL element
22
- this.$element = $(element);
23
-
24
- // B: Set options
25
- this.options = $.extend({}, this.defaults(), options);
26
-
27
- // C: Check deprecations
28
- if (this.options.onlabel === Toggle.DEPRECATION.value) {
29
- if (this.$element.attr("data-on")) {
30
- Toggle.DEPRECATION.log(
31
- Toggle.DEPRECATION.ATTRIBUTE,
32
- "data-on",
33
- "data-onlabel"
34
- );
35
- this.options.onlabel = this.$element.attr("data-on");
36
- } else if (options.on) {
37
- Toggle.DEPRECATION.log(Toggle.DEPRECATION.OPTION, "on", "onlabel");
38
- this.options.onlabel = options.on;
39
- } else {
40
- this.options.onlabel = Toggle.DEFAULTS.onlabel;
41
- }
42
- }
43
- if (this.options.offlabel === Toggle.DEPRECATION.value) {
44
- if (this.$element.attr("data-off")) {
45
- Toggle.DEPRECATION.log(
46
- Toggle.DEPRECATION.ATTRIBUTE,
47
- "data-off",
48
- "data-offlabel"
49
- );
50
- this.options.offlabel = this.$element.attr("data-off");
51
- } else if (options.off) {
52
- Toggle.DEPRECATION.log(Toggle.DEPRECATION.OPTION, "off", "offlabel");
53
- this.options.offlabel = options.off;
54
- } else {
55
- this.options.offlabel = Toggle.DEFAULTS.offlabel;
56
- }
57
- }
58
-
59
- // LAST: Render Toggle
60
- this.render();
61
- };
62
-
63
- Toggle.DEPRECATION = {
64
- value:
65
- "BOOTSTRAP TOGGLE DEPRECATION CHECK -- a0Jhux0QySypjjs4tLtEo8xT2kx0AbYaq9K6mgNjWSs0HF0L8T8J0M0o3Kr7zkm7 --",
66
- ATTRIBUTE: "attribute",
67
- OPTION: "option",
68
- log: function (type, oldlabel, newlabel) {
69
- console.warn(
70
- `Bootstrap Toggle deprecation warning: Using ${oldlabel} ${type} is deprected. Use ${newlabel} instead.`
71
- );
72
- },
73
- };
74
-
75
- Toggle.DEFAULTS = {
76
- onlabel: "On",
77
- offlabel: "Off",
78
- onstyle: "primary",
79
- offstyle: "secondary",
80
- onvalue: null,
81
- offvalue: null,
82
- ontitle: null,
83
- offtitle: null,
84
- size: "normal",
85
- style: "",
86
- width: null,
87
- height: null,
88
- tabindex: 0,
89
- tristate: false,
90
- name: null,
91
- };
92
-
93
- Toggle.prototype.defaults = function () {
94
- return {
95
- onlabel:
96
- this.$element.attr("data-onlabel") ||
97
- Toggle.DEPRECATION.value ||
98
- Toggle.DEFAULTS.onlabel,
99
- offlabel:
100
- this.$element.attr("data-offlabel") ||
101
- Toggle.DEPRECATION.value ||
102
- Toggle.DEFAULTS.offlabel,
103
- onstyle: this.$element.attr("data-onstyle") || Toggle.DEFAULTS.onstyle,
104
- offstyle: this.$element.attr("data-offstyle") || Toggle.DEFAULTS.offstyle,
105
- onvalue:
106
- this.$element.attr("value") ||
107
- this.$element.attr("data-onvalue") ||
108
- Toggle.DEFAULTS.onvalue,
109
- offvalue: this.$element.attr("data-offvalue") || Toggle.DEFAULTS.offvalue,
110
- ontitle:
111
- this.$element.attr("data-ontitle") ||
112
- this.$element.attr("title") ||
113
- Toggle.DEFAULTS.ontitle,
114
- offtitle:
115
- this.$element.attr("data-offtitle") ||
116
- this.$element.attr("title") ||
117
- Toggle.DEFAULTS.offtitle,
118
- size: this.$element.attr("data-size") || Toggle.DEFAULTS.size,
119
- style: this.$element.attr("data-style") || Toggle.DEFAULTS.style,
120
- width: this.$element.attr("data-width") || Toggle.DEFAULTS.width,
121
- height: this.$element.attr("data-height") || Toggle.DEFAULTS.height,
122
- tabindex: this.$element.attr("tabindex") || Toggle.DEFAULTS.tabindex,
123
- tristate: this.$element.is("[tristate]") || Toggle.DEFAULTS.tristate,
124
- name: this.$element.attr("name") || Toggle.DEFAULTS.name,
125
- };
126
- };
127
-
128
- Toggle.prototype.render = function () {
129
- // 0: Parse size
130
- let size;
131
- switch (this.options.size) {
132
- case "large":
133
- case "lg":
134
- size = "btn-lg";
135
- break;
136
- case "small":
137
- case "sm":
138
- size = "btn-sm";
139
- break;
140
- case "mini":
141
- case "xs":
142
- size = "btn-xs";
143
- break;
144
- default:
145
- size = "";
146
- break;
147
- }
148
-
149
- // 1: On
150
- let $toggleOn = $('<span class="btn">')
151
- .html(this.options.onlabel)
152
- .addClass("btn-" + this.options.onstyle + " " + size);
153
- if (this.options.ontitle) {
154
- $toggleOn.attr("title", this.options.ontitle);
155
- }
156
-
157
- // 2: Off
158
- let $toggleOff = $('<span class="btn">')
159
- .html(this.options.offlabel)
160
- .addClass("btn-" + this.options.offstyle + " " + size);
161
- if (this.options.offtitle) {
162
- $toggleOff.attr("title", this.options.offtitle);
163
- }
164
-
165
- // 3: Handle
166
- let $toggleHandle = $('<span class="toggle-handle btn">').addClass(size);
167
-
168
- // 4: Toggle Group
169
- let $toggleGroup = $('<div class="toggle-group">').append(
170
- $toggleOn,
171
- $toggleOff,
172
- $toggleHandle
173
- );
174
-
175
- // 5: Toggle
176
- let $toggle = $(
177
- '<div class="toggle btn" data-toggle="toggle" role="button">'
178
- )
179
- .addClass(
180
- this.$element.prop("checked")
181
- ? "btn-" + this.options.onstyle
182
- : "btn-" + this.options.offstyle + " off"
183
- )
184
- .addClass(size)
185
- .addClass(this.options.style)
186
- .attr("tabindex", this.options.tabindex);
187
- if (this.$element.prop("disabled") || this.$element.prop("readonly")) {
188
- $toggle.addClass("disabled");
189
- $toggle.attr("disabled", "disabled");
190
- }
191
-
192
- // 6: Set form values
193
- if (this.options.onvalue) this.$element.val(this.options.onvalue);
194
- let $invElement = null;
195
- if (this.options.offvalue) {
196
- $invElement = this.$element.clone();
197
- $invElement.val(this.options.offvalue);
198
- $invElement.attr("data-toggle", "invert-toggle");
199
- $invElement.removeAttr("id");
200
- $invElement.prop("checked", !this.$element.prop("checked"));
201
- }
202
-
203
- // 7: Replace HTML checkbox with Toggle-Button
204
- this.$element.wrap($toggle);
205
- $.extend(this, {
206
- $toggle: this.$element.parent(),
207
- $toggleOn: $toggleOn,
208
- $toggleOff: $toggleOff,
209
- $toggleGroup: $toggleGroup,
210
- $invElement: $invElement,
211
- });
212
- this.$toggle.append($invElement, $toggleGroup);
213
-
214
- // 8: Set button W/H, lineHeight
215
- {
216
- // A: Set style W/H
217
- if (this.options.width) {
218
- this.$toggle.css("width", this.options.width);
219
- } else {
220
- this.$toggle.css("min-width", "100px"); // First approach for better calculation
221
- this.$toggle.css(
222
- "min-width",
223
- `${
224
- Math.max($toggleOn.outerWidth(), $toggleOff.outerWidth()) +
225
- $toggleHandle.outerWidth() / 2
226
- }px`
227
- );
228
- }
229
-
230
- if (this.options.height) {
231
- this.$toggle.css("height", this.options.height);
232
- } else {
233
- this.$toggle.css("min-height", "36px"); // First approach for better calculation
234
- this.$toggle.css(
235
- "min-height",
236
- `${Math.max($toggleOn.outerHeight(), $toggleOff.outerHeight())}px`
237
- );
238
- }
239
-
240
- // B: Apply on/off class
241
- $toggleOn.addClass("toggle-on");
242
- $toggleOff.addClass("toggle-off");
243
-
244
- // C: Finally, set lineHeight if needed
245
- if (this.options.height) {
246
- $toggleOn.css("line-height", $toggleOn.height() + "px");
247
- $toggleOff.css("line-height", $toggleOff.height() + "px");
248
- }
249
- }
250
-
251
- // 9: Add listeners
252
- this.$toggle.on("touchstart", (e) => {
253
- toggleActionPerformed(e, this);
254
- });
255
- this.$toggle.on("click", (e) => {
256
- toggleActionPerformed(e, this);
257
- });
258
- this.$toggle.on("keypress", (e) => {
259
- if (e.key == " ") {
260
- toggleActionPerformed(e, this);
261
- }
262
- });
263
-
264
- if (this.$element.prop("id")) {
265
- $('label[for="' + this.$element.prop("id") + '"]').on(
266
- "touchstart click",
267
- (_e) => {
268
- this.toggle();
269
- this.$toggle.focus();
270
- }
271
- );
272
- }
273
-
274
- // 10: Set elements to bootstrap object (NOT NEEDED)
275
- // 11: Keep reference to this instance for subsequent calls via `getElementById().bootstrapToggle()` (NOT NEEDED)
276
- };
277
-
278
- /**
279
- * Trigger actions
280
- * @param {Event} e event
281
- * @param {Toggle} target Toggle
282
- */
283
- function toggleActionPerformed(e, target) {
284
- if (target.options.tristate) {
285
- if (target.$toggle.hasClass("indeterminate")) {
286
- target.determinate(true);
287
- target.toggle();
288
- } else {
289
- target.indeterminate();
290
- }
291
- } else {
292
- target.toggle();
293
- }
294
- e.preventDefault();
295
- }
296
-
297
- Toggle.prototype.toggle = function (silent = false) {
298
- if (this.$element.prop("checked")) this.off(silent);
299
- else this.on(silent);
300
- };
301
-
302
- Toggle.prototype.on = function (silent = false) {
303
- if (this.$element.prop("disabled") || this.$element.prop("readonly"))
304
- return false;
305
- this.$toggle
306
- .removeClass("btn-" + this.options.offstyle + " off")
307
- .addClass("btn-" + this.options.onstyle);
308
- this.$element.prop("checked", true);
309
- if (this.$invElement) this.$invElement.prop("checked", false);
310
- if (!silent) this.trigger();
311
- };
312
-
313
- Toggle.prototype.off = function (silent = false) {
314
- if (this.$element.prop("disabled") || this.$element.prop("readonly"))
315
- return false;
316
- this.$toggle
317
- .removeClass("btn-" + this.options.onstyle)
318
- .addClass("btn-" + this.options.offstyle + " off");
319
- this.$element.prop("checked", false);
320
- if (this.$invElement) this.$invElement.prop("checked", true);
321
- if (!silent) this.trigger();
322
- };
323
-
324
- Toggle.prototype.indeterminate = function (silent = false) {
325
- if (
326
- !this.options.tristate ||
327
- this.$element.prop("disabled") ||
328
- this.$element.prop("readonly")
329
- )
330
- return false;
331
- this.$toggle.addClass("indeterminate");
332
- this.$element.prop("indeterminate", true);
333
- this.$element.removeAttr("name");
334
- if (this.$invElement) this.$invElement.prop("indeterminate", true);
335
- if (this.$invElement) this.$invElement.removeAttr("name");
336
- if (!silent) this.trigger();
337
- };
338
-
339
- Toggle.prototype.determinate = function (silent = false) {
340
- if (
341
- !this.options.tristate ||
342
- this.$element.prop("disabled") ||
343
- this.$element.prop("readonly")
344
- )
345
- return false;
346
- this.$toggle.removeClass("indeterminate");
347
- this.$element.prop("indeterminate", false);
348
- if (this.options.name) this.$element.attr("name", this.options.name);
349
- if (this.$invElement) this.$invElement.prop("indeterminate", false);
350
- if (this.$invElement && this.options.name)
351
- this.$invElement.attr("name", this.options.name);
352
- if (!silent) this.trigger();
353
- };
354
-
355
- Toggle.prototype.enable = function () {
356
- this.$toggle.removeClass("disabled");
357
- this.$toggle.removeAttr("disabled");
358
- this.$element.prop("disabled", false);
359
- this.$element.prop("readonly", false);
360
- if (this.$invElement) {
361
- this.$invElement.prop("disabled", false);
362
- this.$invElement.prop("readonly", false);
363
- }
364
- };
365
-
366
- Toggle.prototype.disable = function () {
367
- this.$toggle.addClass("disabled");
368
- this.$toggle.attr("disabled", "disabled");
369
- this.$element.prop("disabled", true);
370
- this.$element.prop("readonly", false);
371
- if (this.$invElement) {
372
- this.$invElement.prop("disabled", true);
373
- this.$invElement.prop("readonly", false);
374
- }
375
- };
376
-
377
- Toggle.prototype.readonly = function () {
378
- this.$toggle.addClass("disabled");
379
- this.$toggle.attr("disabled", "disabled");
380
- this.$element.prop("disabled", false);
381
- this.$element.prop("readonly", true);
382
- if (this.$invElement) {
383
- this.$invElement.prop("disabled", false);
384
- this.$invElement.prop("readonly", true);
385
- }
386
- };
387
-
388
- Toggle.prototype.update = function (silent) {
389
- if (this.$element.prop("disabled")) this.disable();
390
- else if (this.$element.prop("readonly")) this.readonly();
391
- else this.enable();
392
- if (this.$element.prop("checked")) this.on(silent);
393
- else this.off(silent);
394
- };
395
-
396
- Toggle.prototype.trigger = function (silent) {
397
- this.$element.off("change.bs.toggle");
398
- if (!silent) this.$element.change();
399
- this.$element.on(
400
- "change.bs.toggle",
401
- $.proxy(function () {
402
- this.update();
403
- }, this)
404
- );
405
- };
406
-
407
- Toggle.prototype.destroy = function () {
408
- // A: Remove button-group from UI, replace checkbox element
409
- this.$element.off("change.bs.toggle");
410
- this.$toggleGroup.remove();
411
- if (this.$invElement) this.$invElement.remove();
412
-
413
- // B: Delete internal refs
414
- this.$element.removeData("bs.toggle");
415
- this.$element.unwrap();
416
- };
417
-
418
- // TOGGLE PLUGIN DEFINITION
419
- // ========================
420
-
421
- function Plugin(option) {
422
- let optArg = Array.prototype.slice.call(arguments, 1)[0];
423
-
424
- return this.each(function () {
425
- let $this = $(this);
426
- let data = $this.data("bs.toggle");
427
- let options = typeof option == "object" && option;
428
-
429
- if (!data) {
430
- data = new Toggle(this, options);
431
- $this.data("bs.toggle", data);
432
- }
433
- if (
434
- typeof option === "string" &&
435
- data[option] &&
436
- typeof optArg === "boolean"
437
- )
438
- data[option](optArg);
439
- else if (typeof option === "string" && data[option]) data[option]();
440
- //else if (option && !data[option]) console.log('bootstrap-toggle: error: method `'+ option +'` does not exist!');
441
- });
442
- }
443
-
444
- let old = $.fn.bootstrapToggle;
445
-
446
- $.fn.bootstrapToggle = Plugin;
447
- $.fn.bootstrapToggle.Constructor = Toggle;
448
-
449
- // TOGGLE NO CONFLICT
450
- // ==================
451
-
452
- $.fn.toggle.noConflict = function () {
453
- $.fn.bootstrapToggle = old;
454
- return this;
455
- };
456
-
457
- /**
458
- * Replace all `input[type=checkbox][data-toggle="toggle"]` inputs with "Bootstrap-Toggle"
459
- * Executes once page elements have rendered enabling script to be placed in `<head>`
460
- */
461
- $(function () {
462
- $("input[type=checkbox][data-toggle^=toggle]").bootstrapToggle();
463
- });
464
- })(jQuery);
1
+ /* Copyright Notice
2
+ * bootstrap5-toggle v5.1.0
3
+ * https://palcarazm.github.io/bootstrap5-toggle/
4
+ * @author 2011-2014 Min Hur (https://github.com/minhur)
5
+ * @author 2018-2019 Brent Ely (https://github.com/gitbrent)
6
+ * @author 2022 Pablo Alcaraz Martínez (https://github.com/palcarazm)
7
+ * @funding GitHub Sponsors
8
+ * @see https://github.com/sponsors/palcarazm
9
+ * @license MIT
10
+ * @see https://github.com/palcarazm/bootstrap5-toggle/blob/master/LICENSE
11
+ */
12
+
13
+
14
+ "use strict";
15
+ function sanitize(text) {
16
+ if (!text) return text; // handle null or undefined
17
+ var map = {
18
+ "&": "&amp;",
19
+ "<": "&lt;",
20
+ ">": "&gt;",
21
+ '"': "&quot;",
22
+ "'": "&#39;",
23
+ "/": "&#x2F;",
24
+ };
25
+ return text.replace(/[&<>"'/]/g, function (m) {
26
+ return map[m];
27
+ });
28
+ }
29
+
30
+ +(function ($) {
31
+ // TOGGLE PUBLIC CLASS DEFINITION
32
+ // ==============================
33
+
34
+ let Toggle = function (element, options) {
35
+ // A: Capture ref to HMTL element
36
+ this.$element = $(element);
37
+
38
+ // B: Set options
39
+ this.options = $.extend({}, this.defaults(), options);
40
+
41
+ // C: Check deprecations
42
+ if (this.options.onlabel === Toggle.DEPRECATION.value) {
43
+ if (sanitize(this.$element.attr("data-on"))) {
44
+ Toggle.DEPRECATION.log(
45
+ Toggle.DEPRECATION.ATTRIBUTE,
46
+ "data-on",
47
+ "data-onlabel"
48
+ );
49
+ this.options.onlabel = sanitize(this.$element.attr("data-on"));
50
+ } else if (options.on) {
51
+ Toggle.DEPRECATION.log(Toggle.DEPRECATION.OPTION, "on", "onlabel");
52
+ this.options.onlabel = options.on;
53
+ } else {
54
+ this.options.onlabel = Toggle.DEFAULTS.onlabel;
55
+ }
56
+ }
57
+ if (this.options.offlabel === Toggle.DEPRECATION.value) {
58
+ if (sanitize(this.$element.attr("data-off"))) {
59
+ Toggle.DEPRECATION.log(
60
+ Toggle.DEPRECATION.ATTRIBUTE,
61
+ "data-off",
62
+ "data-offlabel"
63
+ );
64
+ this.options.offlabel = sanitize(this.$element.attr("data-off"));
65
+ } else if (options.off) {
66
+ Toggle.DEPRECATION.log(Toggle.DEPRECATION.OPTION, "off", "offlabel");
67
+ this.options.offlabel = options.off;
68
+ } else {
69
+ this.options.offlabel = Toggle.DEFAULTS.offlabel;
70
+ }
71
+ }
72
+
73
+ // LAST: Render Toggle
74
+ this.render();
75
+ };
76
+
77
+ Toggle.DEPRECATION = {
78
+ value:
79
+ "BOOTSTRAP TOGGLE DEPRECATION CHECK -- a0Jhux0QySypjjs4tLtEo8xT2kx0AbYaq9K6mgNjWSs0HF0L8T8J0M0o3Kr7zkm7 --",
80
+ ATTRIBUTE: "attribute",
81
+ OPTION: "option",
82
+ log: function (type, oldlabel, newlabel) {
83
+ console.warn(
84
+ `Bootstrap Toggle deprecation warning: Using ${oldlabel} ${type} is deprected. Use ${newlabel} instead.`
85
+ );
86
+ },
87
+ };
88
+
89
+ Toggle.DEFAULTS = {
90
+ onlabel: "On",
91
+ offlabel: "Off",
92
+ onstyle: "primary",
93
+ offstyle: "secondary",
94
+ onvalue: null,
95
+ offvalue: null,
96
+ ontitle: null,
97
+ offtitle: null,
98
+ size: "normal",
99
+ style: "",
100
+ width: null,
101
+ height: null,
102
+ tabindex: 0,
103
+ tristate: false,
104
+ name: null,
105
+ };
106
+
107
+ Toggle.prototype.defaults = function () {
108
+ return {
109
+ onlabel:
110
+ sanitize(this.$element.attr("data-onlabel")) ||
111
+ Toggle.DEPRECATION.value ||
112
+ Toggle.DEFAULTS.onlabel,
113
+ offlabel:
114
+ sanitize(this.$element.attr("data-offlabel")) ||
115
+ Toggle.DEPRECATION.value ||
116
+ Toggle.DEFAULTS.offlabel,
117
+ onstyle:
118
+ sanitize(this.$element.attr("data-onstyle")) || Toggle.DEFAULTS.onstyle,
119
+ offstyle:
120
+ sanitize(this.$element.attr("data-offstyle")) ||
121
+ Toggle.DEFAULTS.offstyle,
122
+ onvalue:
123
+ sanitize(this.$element.attr("value")) ||
124
+ sanitize(this.$element.attr("data-onvalue")) ||
125
+ Toggle.DEFAULTS.onvalue,
126
+ offvalue:
127
+ sanitize(this.$element.attr("data-offvalue")) ||
128
+ Toggle.DEFAULTS.offvalue,
129
+ ontitle:
130
+ sanitize(this.$element.attr("data-ontitle")) ||
131
+ sanitize(this.$element.attr("title")) ||
132
+ Toggle.DEFAULTS.ontitle,
133
+ offtitle:
134
+ sanitize(this.$element.attr("data-offtitle")) ||
135
+ sanitize(this.$element.attr("title")) ||
136
+ Toggle.DEFAULTS.offtitle,
137
+ size: sanitize(this.$element.attr("data-size")) || Toggle.DEFAULTS.size,
138
+ style:
139
+ sanitize(this.$element.attr("data-style")) || Toggle.DEFAULTS.style,
140
+ width:
141
+ sanitize(this.$element.attr("data-width")) || Toggle.DEFAULTS.width,
142
+ height:
143
+ sanitize(this.$element.attr("data-height")) || Toggle.DEFAULTS.height,
144
+ tabindex:
145
+ sanitize(this.$element.attr("tabindex")) || Toggle.DEFAULTS.tabindex,
146
+ tristate: this.$element.is("[tristate]") || Toggle.DEFAULTS.tristate,
147
+ name: sanitize(this.$element.attr("name")) || Toggle.DEFAULTS.name,
148
+ };
149
+ };
150
+
151
+ Toggle.prototype.render = function () {
152
+ // 0: Parse size
153
+ let size;
154
+ switch (this.options.size) {
155
+ case "large":
156
+ case "lg":
157
+ size = "btn-lg";
158
+ break;
159
+ case "small":
160
+ case "sm":
161
+ size = "btn-sm";
162
+ break;
163
+ case "mini":
164
+ case "xs":
165
+ size = "btn-xs";
166
+ break;
167
+ default:
168
+ size = "";
169
+ break;
170
+ }
171
+
172
+ // 1: On
173
+ let $toggleOn = $('<span class="btn">')
174
+ .html(this.options.onlabel)
175
+ .addClass("btn-" + this.options.onstyle + " " + size);
176
+ if (this.options.ontitle) {
177
+ $toggleOn.attr("title", this.options.ontitle);
178
+ }
179
+
180
+ // 2: Off
181
+ let $toggleOff = $('<span class="btn">')
182
+ .html(this.options.offlabel)
183
+ .addClass("btn-" + this.options.offstyle + " " + size);
184
+ if (this.options.offtitle) {
185
+ $toggleOff.attr("title", this.options.offtitle);
186
+ }
187
+
188
+ // 3: Handle
189
+ let $toggleHandle = $('<span class="toggle-handle btn">').addClass(size);
190
+
191
+ // 4: Toggle Group
192
+ let $toggleGroup = $('<div class="toggle-group">').append(
193
+ $toggleOn,
194
+ $toggleOff,
195
+ $toggleHandle
196
+ );
197
+
198
+ // 5: Toggle
199
+ let $toggle = $(
200
+ '<div class="toggle btn" data-toggle="toggle" role="button">'
201
+ )
202
+ .addClass(
203
+ this.$element.prop("checked")
204
+ ? "btn-" + this.options.onstyle
205
+ : "btn-" + this.options.offstyle + " off"
206
+ )
207
+ .addClass(size)
208
+ .addClass(this.options.style)
209
+ .attr("tabindex", this.options.tabindex);
210
+ if (this.$element.prop("disabled") || this.$element.prop("readonly")) {
211
+ $toggle.addClass("disabled");
212
+ $toggle.attr("disabled", "disabled");
213
+ }
214
+
215
+ // 6: Set form values
216
+ if (this.options.onvalue) this.$element.val(this.options.onvalue);
217
+ let $invElement = null;
218
+ if (this.options.offvalue) {
219
+ $invElement = this.$element.clone();
220
+ $invElement.val(this.options.offvalue);
221
+ $invElement.attr("data-toggle", "invert-toggle");
222
+ $invElement.removeAttr("id");
223
+ $invElement.prop("checked", !this.$element.prop("checked"));
224
+ }
225
+
226
+ // 7: Replace HTML checkbox with Toggle-Button
227
+ this.$element.wrap($toggle);
228
+ $.extend(this, {
229
+ $toggle: this.$element.parent(),
230
+ $toggleOn: $toggleOn,
231
+ $toggleOff: $toggleOff,
232
+ $toggleGroup: $toggleGroup,
233
+ $invElement: $invElement,
234
+ });
235
+ this.$toggle.append($invElement, $toggleGroup);
236
+
237
+ // 8: Set button W/H, lineHeight
238
+ {
239
+ // A: Set style W/H
240
+ if (this.options.width) {
241
+ this.$toggle.css("width", this.options.width);
242
+ } else {
243
+ this.$toggle.css("min-width", "100px"); // First approach for better calculation
244
+ this.$toggle.css(
245
+ "min-width",
246
+ `${
247
+ Math.max($toggleOn.outerWidth(), $toggleOff.outerWidth()) +
248
+ $toggleHandle.outerWidth() / 2
249
+ }px`
250
+ );
251
+ }
252
+
253
+ if (this.options.height) {
254
+ this.$toggle.css("height", this.options.height);
255
+ } else {
256
+ this.$toggle.css("min-height", "36px"); // First approach for better calculation
257
+ this.$toggle.css(
258
+ "min-height",
259
+ `${Math.max($toggleOn.outerHeight(), $toggleOff.outerHeight())}px`
260
+ );
261
+ }
262
+
263
+ // B: Apply on/off class
264
+ $toggleOn.addClass("toggle-on");
265
+ $toggleOff.addClass("toggle-off");
266
+
267
+ // C: Finally, set lineHeight if needed
268
+ if (this.options.height) {
269
+ $toggleOn.css("line-height", $toggleOn.height() + "px");
270
+ $toggleOff.css("line-height", $toggleOff.height() + "px");
271
+ }
272
+ }
273
+
274
+ // 9: Add listeners
275
+ this.$toggle.on("touchstart", (e) => {
276
+ toggleActionPerformed(e, this);
277
+ });
278
+ this.$toggle.on("click", (e) => {
279
+ toggleActionPerformed(e, this);
280
+ });
281
+ this.$toggle.on("keypress", (e) => {
282
+ if (e.key == " ") {
283
+ toggleActionPerformed(e, this);
284
+ }
285
+ });
286
+
287
+ if (this.$element.prop("id")) {
288
+ $('label[for="' + this.$element.prop("id") + '"]').on(
289
+ "touchstart click",
290
+ (_e) => {
291
+ this.toggle();
292
+ this.$toggle.focus();
293
+ }
294
+ );
295
+ }
296
+
297
+ // 10: Set elements to bootstrap object (NOT NEEDED)
298
+ // 11: Keep reference to this instance for subsequent calls via `getElementById().bootstrapToggle()` (NOT NEEDED)
299
+ };
300
+
301
+ /**
302
+ * Trigger actions
303
+ * @param {Event} e event
304
+ * @param {Toggle} target Toggle
305
+ */
306
+ function toggleActionPerformed(e, target) {
307
+ if (target.options.tristate) {
308
+ if (target.$toggle.hasClass("indeterminate")) {
309
+ target.determinate(true);
310
+ target.toggle();
311
+ } else {
312
+ target.indeterminate();
313
+ }
314
+ } else {
315
+ target.toggle();
316
+ }
317
+ }
318
+
319
+ Toggle.prototype.toggle = function (silent = false) {
320
+ if (this.$element.prop("checked")) this.off(silent);
321
+ else this.on(silent);
322
+ };
323
+
324
+ Toggle.prototype.on = function (silent = false) {
325
+ if (this.$element.prop("disabled") || this.$element.prop("readonly"))
326
+ return false;
327
+ this.$toggle
328
+ .removeClass("btn-" + this.options.offstyle + " off")
329
+ .addClass("btn-" + this.options.onstyle);
330
+ this.$element.prop("checked", true);
331
+ if (this.$invElement) this.$invElement.prop("checked", false);
332
+ if (!silent) this.trigger();
333
+ };
334
+
335
+ Toggle.prototype.off = function (silent = false) {
336
+ if (this.$element.prop("disabled") || this.$element.prop("readonly"))
337
+ return false;
338
+ this.$toggle
339
+ .removeClass("btn-" + this.options.onstyle)
340
+ .addClass("btn-" + this.options.offstyle + " off");
341
+ this.$element.prop("checked", false);
342
+ if (this.$invElement) this.$invElement.prop("checked", true);
343
+ if (!silent) this.trigger();
344
+ };
345
+
346
+ Toggle.prototype.indeterminate = function (silent = false) {
347
+ if (
348
+ !this.options.tristate ||
349
+ this.$element.prop("disabled") ||
350
+ this.$element.prop("readonly")
351
+ )
352
+ return false;
353
+ this.$toggle.addClass("indeterminate");
354
+ this.$element.prop("indeterminate", true);
355
+ this.$element.removeAttr("name");
356
+ if (this.$invElement) this.$invElement.prop("indeterminate", true);
357
+ if (this.$invElement) this.$invElement.removeAttr("name");
358
+ if (!silent) this.trigger();
359
+ };
360
+
361
+ Toggle.prototype.determinate = function (silent = false) {
362
+ if (
363
+ !this.options.tristate ||
364
+ this.$element.prop("disabled") ||
365
+ this.$element.prop("readonly")
366
+ )
367
+ return false;
368
+ this.$toggle.removeClass("indeterminate");
369
+ this.$element.prop("indeterminate", false);
370
+ if (this.options.name) this.$element.attr("name", this.options.name);
371
+ if (this.$invElement) this.$invElement.prop("indeterminate", false);
372
+ if (this.$invElement && this.options.name)
373
+ this.$invElement.attr("name", this.options.name);
374
+ if (!silent) this.trigger();
375
+ };
376
+
377
+ Toggle.prototype.enable = function () {
378
+ this.$toggle.removeClass("disabled");
379
+ this.$toggle.removeAttr("disabled");
380
+ this.$element.prop("disabled", false);
381
+ this.$element.prop("readonly", false);
382
+ if (this.$invElement) {
383
+ this.$invElement.prop("disabled", false);
384
+ this.$invElement.prop("readonly", false);
385
+ }
386
+ };
387
+
388
+ Toggle.prototype.disable = function () {
389
+ this.$toggle.addClass("disabled");
390
+ this.$toggle.attr("disabled", "disabled");
391
+ this.$element.prop("disabled", true);
392
+ this.$element.prop("readonly", false);
393
+ if (this.$invElement) {
394
+ this.$invElement.prop("disabled", true);
395
+ this.$invElement.prop("readonly", false);
396
+ }
397
+ };
398
+
399
+ Toggle.prototype.readonly = function () {
400
+ this.$toggle.addClass("disabled");
401
+ this.$toggle.attr("disabled", "disabled");
402
+ this.$element.prop("disabled", false);
403
+ this.$element.prop("readonly", true);
404
+ if (this.$invElement) {
405
+ this.$invElement.prop("disabled", false);
406
+ this.$invElement.prop("readonly", true);
407
+ }
408
+ };
409
+
410
+ Toggle.prototype.update = function (silent) {
411
+ if (this.$element.prop("disabled")) this.disable();
412
+ else if (this.$element.prop("readonly")) this.readonly();
413
+ else this.enable();
414
+ if (this.$element.prop("checked")) this.on(silent);
415
+ else this.off(silent);
416
+ };
417
+
418
+ Toggle.prototype.trigger = function (silent) {
419
+ this.$element.off("change.bs.toggle");
420
+ if (!silent) this.$element.change();
421
+ this.$element.on(
422
+ "change.bs.toggle",
423
+ $.proxy(function () {
424
+ this.update();
425
+ }, this)
426
+ );
427
+ };
428
+
429
+ Toggle.prototype.destroy = function () {
430
+ // A: Remove button-group from UI, replace checkbox element
431
+ this.$element.off("change.bs.toggle");
432
+ this.$toggleGroup.remove();
433
+ if (this.$invElement) this.$invElement.remove();
434
+
435
+ // B: Delete internal refs
436
+ this.$element.removeData("bs.toggle");
437
+ this.$element.unwrap();
438
+ };
439
+
440
+ Toggle.prototype.rerender = function () {
441
+ this.destroy();
442
+ this.$element.bootstrapToggle();
443
+ };
444
+
445
+ // TOGGLE PLUGIN DEFINITION
446
+ // ========================
447
+
448
+ function Plugin(option) {
449
+ let optArg = Array.prototype.slice.call(arguments, 1)[0];
450
+
451
+ return this.each(function () {
452
+ let $this = $(this);
453
+ let data = $this.data("bs.toggle");
454
+ let options = typeof option == "object" && option;
455
+
456
+ if (!data) {
457
+ data = new Toggle(this, options);
458
+ $this.data("bs.toggle", data);
459
+ }
460
+ if (
461
+ typeof option === "string" &&
462
+ data[option] &&
463
+ typeof optArg === "boolean"
464
+ )
465
+ data[option](optArg);
466
+ else if (typeof option === "string" && data[option]) data[option]();
467
+ //else if (option && !data[option]) console.log('bootstrap-toggle: error: method `'+ option +'` does not exist!');
468
+ });
469
+ }
470
+
471
+ let old = $.fn.bootstrapToggle;
472
+
473
+ $.fn.bootstrapToggle = Plugin;
474
+ $.fn.bootstrapToggle.Constructor = Toggle;
475
+
476
+ // TOGGLE NO CONFLICT
477
+ // ==================
478
+
479
+ $.fn.toggle.noConflict = function () {
480
+ $.fn.bootstrapToggle = old;
481
+ return this;
482
+ };
483
+
484
+ /**
485
+ * Replace all `input[type=checkbox][data-toggle="toggle"]` inputs with "Bootstrap-Toggle"
486
+ * Executes once page elements have rendered enabling script to be placed in `<head>`
487
+ */
488
+ $(function () {
489
+ $("input[type=checkbox][data-toggle^=toggle]").bootstrapToggle();
490
+ });
491
+ })(jQuery);