2
0
mirror of https://github.com/tenrok/bootstrap.git synced 2026-05-15 11:59:39 +03:00
Files
bootstrap/js/src/button.js
T
Kotas Vlastimil 866e99b00c Button toggling - trigger change event on input
Bootstrap’s .button styles can be applied to other elements, such as labels, to provide checkbox or radio style button toggling.

When the checkbox or radio state is changed, there should be triggered the change event. Currently, the change event is triggered on the Button, which is not correct. Only input fields do support the change event.
2016-01-14 20:26:32 +01:00

174 lines
4.2 KiB
JavaScript

/**
* --------------------------------------------------------------------------
* Bootstrap (v4.0.0-alpha.2): button.js
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
* --------------------------------------------------------------------------
*/
const Button = (($) => {
/**
* ------------------------------------------------------------------------
* Constants
* ------------------------------------------------------------------------
*/
const NAME = 'button'
const VERSION = '4.0.0-alpha.2'
const DATA_KEY = 'bs.button'
const EVENT_KEY = `.${DATA_KEY}`
const DATA_API_KEY = '.data-api'
const JQUERY_NO_CONFLICT = $.fn[NAME]
const ClassName = {
ACTIVE : 'active',
BUTTON : 'btn',
FOCUS : 'focus'
}
const Selector = {
DATA_TOGGLE_CARROT : '[data-toggle^="button"]',
DATA_TOGGLE : '[data-toggle="buttons"]',
INPUT : 'input',
ACTIVE : '.active',
BUTTON : '.btn'
}
const Event = {
CLICK_DATA_API : `click${EVENT_KEY}${DATA_API_KEY}`,
FOCUS_BLUR_DATA_API : `focus${EVENT_KEY}${DATA_API_KEY} `
+ `blur${EVENT_KEY}${DATA_API_KEY}`
}
/**
* ------------------------------------------------------------------------
* Class Definition
* ------------------------------------------------------------------------
*/
class Button {
constructor(element) {
this._element = element
}
// getters
static get VERSION() {
return VERSION
}
// public
toggle() {
let triggerChangeEvent = true
let rootElement = $(this._element).closest(
Selector.DATA_TOGGLE
)[0]
if (rootElement) {
let input = $(this._element).find(Selector.INPUT)[0]
if (input) {
if (input.type === 'radio') {
if (input.checked &&
$(this._element).hasClass(ClassName.ACTIVE)) {
triggerChangeEvent = false
} else {
let activeElement = $(rootElement).find(Selector.ACTIVE)[0]
if (activeElement) {
$(activeElement).removeClass(ClassName.ACTIVE)
}
}
}
if (triggerChangeEvent) {
input.checked = !$(this._element).hasClass(ClassName.ACTIVE)
$(input).trigger('change')
}
}
} else {
this._element.setAttribute('aria-pressed',
!$(this._element).hasClass(ClassName.ACTIVE))
}
if (triggerChangeEvent) {
$(this._element).toggleClass(ClassName.ACTIVE)
}
}
dispose() {
$.removeData(this._element, DATA_KEY)
this._element = null
}
// static
static _jQueryInterface(config) {
return this.each(function () {
let data = $(this).data(DATA_KEY)
if (!data) {
data = new Button(this)
$(this).data(DATA_KEY, data)
}
if (config === 'toggle') {
data[config]()
}
})
}
}
/**
* ------------------------------------------------------------------------
* Data Api implementation
* ------------------------------------------------------------------------
*/
$(document)
.on(Event.CLICK_DATA_API, Selector.DATA_TOGGLE_CARROT, (event) => {
event.preventDefault()
let button = event.target
if (!$(button).hasClass(ClassName.BUTTON)) {
button = $(button).closest(Selector.BUTTON)
}
Button._jQueryInterface.call($(button), 'toggle')
})
.on(Event.FOCUS_BLUR_DATA_API, Selector.DATA_TOGGLE_CARROT, (event) => {
let button = $(event.target).closest(Selector.BUTTON)[0]
$(button).toggleClass(ClassName.FOCUS, /^focus(in)?$/.test(event.type))
})
/**
* ------------------------------------------------------------------------
* jQuery
* ------------------------------------------------------------------------
*/
$.fn[NAME] = Button._jQueryInterface
$.fn[NAME].Constructor = Button
$.fn[NAME].noConflict = function () {
$.fn[NAME] = JQUERY_NO_CONFLICT
return Button._jQueryInterface
}
return Button
})(jQuery)
export default Button