1
|
// Native Javascript for Bootstrap 3 | Button
|
2
|
// by dnp_theme
|
3
|
|
4
|
(function(factory){
|
5
|
|
6
|
// CommonJS/RequireJS and "native" compatibility
|
7
|
if(typeof module !== "undefined" && typeof exports == "object") {
|
8
|
// A commonJS/RequireJS environment
|
9
|
if(typeof window != "undefined") {
|
10
|
// Window and document exist, so return the factory's return value.
|
11
|
module.exports = factory();
|
12
|
} else {
|
13
|
// Let the user give the factory a Window and Document.
|
14
|
module.exports = factory;
|
15
|
}
|
16
|
} else {
|
17
|
// Assume a traditional browser.
|
18
|
window.Button = factory();
|
19
|
}
|
20
|
|
21
|
})(function(){
|
22
|
|
23
|
// BUTTON DEFINITION
|
24
|
// ===================
|
25
|
var Button = function( element, option ) {
|
26
|
this.btn = typeof element === 'object' ? element : document.querySelector(element);
|
27
|
this.option = typeof option === 'string' ? option : null;
|
28
|
|
29
|
this.init();
|
30
|
};
|
31
|
|
32
|
// BUTTON METHODS
|
33
|
// ================
|
34
|
Button.prototype = {
|
35
|
|
36
|
init : function() {
|
37
|
var self = this;
|
38
|
this.actions();
|
39
|
|
40
|
if ( /btn/.test(this.btn.className) ) {
|
41
|
if ( this.option && this.option !== 'reset' ) {
|
42
|
|
43
|
this.state = this.btn.getAttribute('data-'+this.option+'-text') || null;
|
44
|
|
45
|
!this.btn.getAttribute('data-original-text') && this.btn.setAttribute('data-original-text',self.btn.innerHTML.replace(/^\s+|\s+$/g, ''));
|
46
|
this.setState();
|
47
|
|
48
|
} else if ( this.option === 'reset' ) {
|
49
|
this.reset();
|
50
|
}
|
51
|
}
|
52
|
|
53
|
if ( /btn-group/.test(this.btn.className) ) {
|
54
|
this.btn.addEventListener('click', this.toggle, false);
|
55
|
}
|
56
|
},
|
57
|
|
58
|
actions : function() {
|
59
|
var self = this,
|
60
|
changeEvent = (('CustomEvent' in window) && window.dispatchEvent)
|
61
|
? new CustomEvent('bs.button.change') : null; // The custom event that will be triggered on demand
|
62
|
|
63
|
// assign event to a trigger function
|
64
|
function triggerChange(t) { if (changeEvent) { t.dispatchEvent(changeEvent); } }
|
65
|
|
66
|
this.setState = function() {
|
67
|
if ( this.option === 'loading' ) {
|
68
|
this.addClass(this.btn,'disabled');
|
69
|
this.btn.setAttribute('disabled','disabled');
|
70
|
}
|
71
|
this.btn.innerHTML = this.state;
|
72
|
},
|
73
|
|
74
|
this.reset = function() {
|
75
|
if ( /disabled/.test(self.btn.className) || self.btn.getAttribute('disabled') === 'disabled' ) {
|
76
|
this.removeClass(this.btn,'disabled');
|
77
|
self.btn.removeAttribute('disabled');
|
78
|
}
|
79
|
self.btn.innerHTML = self.btn.getAttribute('data-original-text');
|
80
|
},
|
81
|
|
82
|
this.toggle = function(e) {
|
83
|
var parent = e.target.parentNode,
|
84
|
label = e.target.tagName === 'LABEL' ? e.target : parent.tagName === 'LABEL' ? parent : null; // the .btn label
|
85
|
|
86
|
if ( !label ) return; //react if a label or its immediate child is clicked
|
87
|
|
88
|
var target = this, //e.currentTarget || e.srcElement; // the button group, the target of the handler function
|
89
|
labels = target.querySelectorAll('.btn'), ll = labels.length, i = 0, // all the button group buttons
|
90
|
input = label.getElementsByTagName('INPUT')[0];
|
91
|
|
92
|
if ( !input ) return; //return if no input found
|
93
|
|
94
|
//manage the dom manipulation
|
95
|
if ( input.type === 'checkbox' ) { //checkboxes
|
96
|
if ( !input.checked ) {
|
97
|
self.addClass(label,'active');
|
98
|
input.getAttribute('checked');
|
99
|
input.setAttribute('checked','checked');
|
100
|
input.checked = true;
|
101
|
} else {
|
102
|
self.removeClass(label,'active');
|
103
|
input.getAttribute('checked');
|
104
|
input.removeAttribute('checked');
|
105
|
input.checked = false;
|
106
|
}
|
107
|
triggerChange(input); //trigger the change for the input
|
108
|
triggerChange(self.btn); //trigger the change for the btn-group
|
109
|
}
|
110
|
|
111
|
if ( input.type === 'radio' ) { // radio buttons
|
112
|
if ( !input.checked ) { // don't trigger if already active
|
113
|
self.addClass(label,'active');
|
114
|
input.setAttribute('checked','checked');
|
115
|
input.checked = true;
|
116
|
triggerChange(self.btn);
|
117
|
triggerChange(input); //trigger the change
|
118
|
|
119
|
for (i;i<ll;i++) {
|
120
|
var l = labels[i];
|
121
|
if ( l !== label && /active/.test(l.className) ) {
|
122
|
var inp = l.getElementsByTagName('INPUT')[0];
|
123
|
self.removeClass(l,'active');
|
124
|
inp.removeAttribute('checked');
|
125
|
inp.checked = false;
|
126
|
triggerChange(inp); // trigger the change
|
127
|
}
|
128
|
}
|
129
|
}
|
130
|
}
|
131
|
},
|
132
|
this.addClass = function(el,c) { // where modern browsers fail, use classList
|
133
|
if (el.classList) { el.classList.add(c); } else { el.className += ' '+c; el.offsetWidth; }
|
134
|
},
|
135
|
this.removeClass = function(el,c) {
|
136
|
if (el.classList) { el.classList.remove(c); } else { el.className = el.className.replace(c,'').replace(/^\s+|\s+$/g,''); el.offsetWidth; }
|
137
|
}
|
138
|
}
|
139
|
}
|
140
|
|
141
|
// BUTTON DATA API
|
142
|
// =================
|
143
|
var Buttons = document.querySelectorAll('[data-toggle=button]'), i = 0, btl = Buttons.length;
|
144
|
for (i;i<btl;i++) {
|
145
|
new Button(Buttons[i]);
|
146
|
}
|
147
|
|
148
|
var ButtonGroups = document.querySelectorAll('[data-toggle=buttons]'), j = 0, bgl = ButtonGroups.length;
|
149
|
for (j;j<bgl;j++) {
|
150
|
new Button(ButtonGroups[j]);
|
151
|
}
|
152
|
|
153
|
return Button;
|
154
|
|
155
|
});
|