button.js 4.28 KB
Newer Older
fat's avatar
fat committed
1
2
/**
 * --------------------------------------------------------------------------
Mark Otto's avatar
Mark Otto committed
3
 * Bootstrap (v4.1.3): button.js
fat's avatar
fat committed
4
5
6
7
 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
 * --------------------------------------------------------------------------
 */

8
9
import $ from 'jquery'

Johann-S's avatar
Johann-S committed
10
11
12
13
14
/**
 * ------------------------------------------------------------------------
 * Constants
 * ------------------------------------------------------------------------
 */
fat's avatar
fat committed
15

Johann-S's avatar
Johann-S committed
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
const NAME                = 'button'
const VERSION             = '4.1.3'
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
fat's avatar
fat committed
52
53
  }

Johann-S's avatar
Johann-S committed
54
55
56
57
  // Getters

  static get VERSION() {
    return VERSION
fat's avatar
fat committed
58
59
  }

Johann-S's avatar
Johann-S committed
60
  // Public
fat's avatar
fat committed
61

Johann-S's avatar
Johann-S committed
62
63
64
65
66
67
  toggle() {
    let triggerChangeEvent = true
    let addAriaPressed = true
    const rootElement = $(this._element).closest(
      Selector.DATA_TOGGLE
    )[0]
fat's avatar
fat committed
68

Johann-S's avatar
Johann-S committed
69
70
    if (rootElement) {
      const input = this._element.querySelector(Selector.INPUT)
71

Johann-S's avatar
Johann-S committed
72
73
74
75
76
77
78
      if (input) {
        if (input.type === 'radio') {
          if (input.checked &&
            this._element.classList.contains(ClassName.ACTIVE)) {
            triggerChangeEvent = false
          } else {
            const activeElement = rootElement.querySelector(Selector.ACTIVE)
79

Johann-S's avatar
Johann-S committed
80
81
            if (activeElement) {
              $(activeElement).removeClass(ClassName.ACTIVE)
fat's avatar
fat committed
82
83
            }
          }
Johann-S's avatar
Johann-S committed
84
        }
fat's avatar
fat committed
85

Johann-S's avatar
Johann-S committed
86
87
88
89
90
91
        if (triggerChangeEvent) {
          if (input.hasAttribute('disabled') ||
            rootElement.hasAttribute('disabled') ||
            input.classList.contains('disabled') ||
            rootElement.classList.contains('disabled')) {
            return
fat's avatar
fat committed
92
          }
Johann-S's avatar
Johann-S committed
93
94
          input.checked = !this._element.classList.contains(ClassName.ACTIVE)
          $(input).trigger('change')
fat's avatar
fat committed
95
96
        }

Johann-S's avatar
Johann-S committed
97
98
        input.focus()
        addAriaPressed = false
99
      }
Johann-S's avatar
Johann-S committed
100
    }
101

Johann-S's avatar
Johann-S committed
102
103
104
    if (addAriaPressed) {
      this._element.setAttribute('aria-pressed',
        !this._element.classList.contains(ClassName.ACTIVE))
fat's avatar
fat committed
105
106
    }

Johann-S's avatar
Johann-S committed
107
108
    if (triggerChangeEvent) {
      $(this._element).toggleClass(ClassName.ACTIVE)
fat's avatar
fat committed
109
    }
Johann-S's avatar
Johann-S committed
110
  }
fat's avatar
fat committed
111

Johann-S's avatar
Johann-S committed
112
113
114
115
  dispose() {
    $.removeData(this._element, DATA_KEY)
    this._element = null
  }
fat's avatar
fat committed
116

Johann-S's avatar
Johann-S committed
117
  // Static
fat's avatar
fat committed
118

Johann-S's avatar
Johann-S committed
119
120
121
  static _jQueryInterface(config) {
    return this.each(function () {
      let data = $(this).data(DATA_KEY)
fat's avatar
fat committed
122

Johann-S's avatar
Johann-S committed
123
124
125
126
127
128
129
130
131
      if (!data) {
        data = new Button(this)
        $(this).data(DATA_KEY, data)
      }

      if (config === 'toggle') {
        data[config]()
      }
    })
fat's avatar
fat committed
132
  }
Johann-S's avatar
Johann-S committed
133
}
fat's avatar
fat committed
134

Johann-S's avatar
Johann-S committed
135
136
137
138
139
/**
 * ------------------------------------------------------------------------
 * Data Api implementation
 * ------------------------------------------------------------------------
 */
fat's avatar
fat committed
140

Johann-S's avatar
Johann-S committed
141
142
143
$(document)
  .on(Event.CLICK_DATA_API, Selector.DATA_TOGGLE_CARROT, (event) => {
    event.preventDefault()
fat's avatar
fat committed
144

Johann-S's avatar
Johann-S committed
145
    let button = event.target
fat's avatar
fat committed
146

Johann-S's avatar
Johann-S committed
147
148
149
    if (!$(button).hasClass(ClassName.BUTTON)) {
      button = $(button).closest(Selector.BUTTON)
    }
fat's avatar
fat committed
150

Johann-S's avatar
Johann-S committed
151
152
153
154
155
156
    Button._jQueryInterface.call($(button), 'toggle')
  })
  .on(Event.FOCUS_BLUR_DATA_API, Selector.DATA_TOGGLE_CARROT, (event) => {
    const button = $(event.target).closest(Selector.BUTTON)[0]
    $(button).toggleClass(ClassName.FOCUS, /^focus(in)?$/.test(event.type))
  })
fat's avatar
fat committed
157

Johann-S's avatar
Johann-S committed
158
159
160
161
162
/**
 * ------------------------------------------------------------------------
 * jQuery
 * ------------------------------------------------------------------------
 */
fat's avatar
fat committed
163

Johann-S's avatar
Johann-S committed
164
165
166
167
168
169
$.fn[NAME] = Button._jQueryInterface
$.fn[NAME].Constructor = Button
$.fn[NAME].noConflict = () => {
  $.fn[NAME] = JQUERY_NO_CONFLICT
  return Button._jQueryInterface
}
fat's avatar
fat committed
170
171

export default Button