aboutsummaryrefslogtreecommitdiffstats
path: root/actionview/app/assets/javascripts/rails-ujs/features/disable.coffee
blob: a8c692ee62d89af1daa626c30568b3a209a547e3 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
#= require_tree ../utils

{ matches, getData, setData, stopEverything, formElements } = Rails

Rails.handleDisabledElement = (e) ->
  element = this
  stopEverything(e) if element.disabled

# Unified function to enable an element (link, button and form)
Rails.enableElement = (e) ->
  if e instanceof Event
    return if isXhrRedirect(e)
    element = e.target
  else
    element = e

  if matches(element, Rails.linkDisableSelector)
    enableLinkElement(element)
  else if matches(element, Rails.buttonDisableSelector) or matches(element, Rails.formEnableSelector)
    enableFormElement(element)
  else if matches(element, Rails.formSubmitSelector)
    enableFormElements(element)

# Unified function to disable an element (link, button and form)
Rails.disableElement = (e) ->
  element = if e instanceof Event then e.target else e
  if matches(element, Rails.linkDisableSelector)
    disableLinkElement(element)
  else if matches(element, Rails.buttonDisableSelector) or matches(element, Rails.formDisableSelector)
    disableFormElement(element)
  else if matches(element, Rails.formSubmitSelector)
    disableFormElements(element)

#  Replace element's html with the 'data-disable-with' after storing original html
#  and prevent clicking on it
disableLinkElement = (element) ->
  replacement = element.getAttribute('data-disable-with')
  if replacement?
    setData(element, 'ujs:enable-with', element.innerHTML) # store enabled state
    element.innerHTML = replacement
  element.addEventListener('click', stopEverything) # prevent further clicking
  setData(element, 'ujs:disabled', true)

# Restore element to its original state which was disabled by 'disableLinkElement' above
enableLinkElement = (element) ->
  originalText = getData(element, 'ujs:enable-with')
  if originalText?
    element.innerHTML = originalText # set to old enabled state
    setData(element, 'ujs:enable-with', null) # clean up cache
  element.removeEventListener('click', stopEverything) # enable element
  setData(element, 'ujs:disabled', null)

# Disables form elements:
#  - Caches element value in 'ujs:enable-with' data store
#  - Replaces element text with value of 'data-disable-with' attribute
#  - Sets disabled property to true
disableFormElements = (form) ->
  formElements(form, Rails.formDisableSelector).forEach(disableFormElement)

disableFormElement = (element) ->
  replacement = element.getAttribute('data-disable-with')
  if replacement?
    if matches(element, 'button')
      setData(element, 'ujs:enable-with', element.innerHTML)
      element.innerHTML = replacement
    else
      setData(element, 'ujs:enable-with', element.value)
      element.value = replacement
  element.disabled = true
  setData(element, 'ujs:disabled', true)

# Re-enables disabled form elements:
#  - Replaces element text with cached value from 'ujs:enable-with' data store (created in `disableFormElements`)
#  - Sets disabled property to false
enableFormElements = (form) ->
  formElements(form, Rails.formEnableSelector).forEach(enableFormElement)

enableFormElement = (element) ->
  originalText = getData(element, 'ujs:enable-with')
  if originalText?
    if matches(element, 'button')
      element.innerHTML = originalText
    else
      element.value = originalText
    setData(element, 'ujs:enable-with', null) # clean up cache
  element.disabled = false
  setData(element, 'ujs:disabled', null)

isXhrRedirect = (event) ->
  xhr = event.detail?[0]
  xhr?.getResponseHeader("X-Xhr-Redirect")?