import {
linkDisableSelector, buttonDisableSelector, formDisableSelector, formEnableSelector, formSubmitSelector
} from “../utils/constants” import { matches, getData, setData } from “../utils/dom” import { stopEverything } from “../utils/event” import { formElements } from “../utils/form” import { isContentEditable } from “../utils/dom”
const handleDisabledElement = function(e) {
const element = this if (element.disabled) { stopEverything(e) }
}
// Unified function to enable an element (link, button and form) const enableElement = (e) => {
let element if (e instanceof Event) { if (isXhrRedirect(e)) { return } element = e.target } else { element = e } if (isContentEditable(element)) { return } if (matches(element, linkDisableSelector)) { return enableLinkElement(element) } else if (matches(element, buttonDisableSelector) || matches(element, formEnableSelector)) { return enableFormElement(element) } else if (matches(element, formSubmitSelector)) { return enableFormElements(element) }
}
// Unified function to disable an element (link, button and form) const disableElement = (e) => {
const element = e instanceof Event ? e.target : e if (isContentEditable(element)) { return } if (matches(element, linkDisableSelector)) { return disableLinkElement(element) } else if (matches(element, buttonDisableSelector) || matches(element, formDisableSelector)) { return disableFormElement(element) } else if (matches(element, formSubmitSelector)) { return disableFormElements(element) }
}
// Replace element’s HTML with the ‘data-disable-with’ after storing original html // and prevent clicking on it var disableLinkElement = function(element) {
if (getData(element, "ujs:disabled")) { return } const replacement = element.getAttribute("data-disable-with") if (replacement != null) { setData(element, "ujs:enable-with", element.innerHTML) // store enabled state element.innerHTML = replacement } element.addEventListener("click", stopEverything) // prevent further clicking return setData(element, "ujs:disabled", true)
}
// Restore element to its original state which was disabled by ‘disableLinkElement’ above var enableLinkElement = function(element) {
const originalText = getData(element, "ujs:enable-with") if (originalText != null) { element.innerHTML = originalText // set to old enabled state setData(element, "ujs:enable-with", null) // clean up cache } element.removeEventListener("click", stopEverything) // enable element return 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 var disableFormElements = form => formElements(form, formDisableSelector).forEach(disableFormElement)
var disableFormElement = function(element) {
if (getData(element, "ujs:disabled")) { return } const replacement = element.getAttribute("data-disable-with") if (replacement != null) { 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 return 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 var enableFormElements = form => formElements(form, formEnableSelector).forEach(element => enableFormElement(element))
var enableFormElement = function(element) {
const originalText = getData(element, "ujs:enable-with") if (originalText != null) { if (matches(element, "button")) { element.innerHTML = originalText } else { element.value = originalText } setData(element, "ujs:enable-with", null) // clean up cache } element.disabled = false return setData(element, "ujs:disabled", null)
}
var isXhrRedirect = function(event) {
const xhr = event.detail ? event.detail[0] : undefined return xhr && xhr.getResponseHeader("X-Xhr-Redirect")
}
export { handleDisabledElement, enableElement, disableElement }