import { formSubmitSelector, buttonClickSelector, inputChangeSelector } from “../utils/constants” import { ajax, isCrossDomain } from “../utils/ajax” import { matches, getData, setData } from “../utils/dom” import { fire, stopEverything } from “../utils/event” import { serializeElement } from “../utils/form” import { isContentEditable } from “../utils/dom”
// Checks “data-remote” if true to handle the request through a XHR request. const isRemote = function(element) {
const value = element.getAttribute("data-remote") return (value != null) && (value !== "false")
}
// Submits “remote” forms and links with ajax const handleRemoteWithRails = (rails) => function(e) {
let data, method, url const element = this if (!isRemote(element)) { return true } if (!fire(element, "ajax:before")) { fire(element, "ajax:stopped") return false } if (isContentEditable(element)) { fire(element, "ajax:stopped") return false } const withCredentials = element.getAttribute("data-with-credentials") const dataType = element.getAttribute("data-type") || "script" if (matches(element, formSubmitSelector)) { // memoized value from clicked submit button const button = getData(element, "ujs:submit-button") method = getData(element, "ujs:submit-button-formmethod") || element.getAttribute("method") || "get" url = getData(element, "ujs:submit-button-formaction") || element.getAttribute("action") || location.href // strip query string if it's a GET request if (method.toUpperCase() === "GET") { url = url.replace(/\?.*$/, "") } if (element.enctype === "multipart/form-data") { data = new FormData(element) if (button != null) { data.append(button.name, button.value) } } else { data = serializeElement(element, button) } setData(element, "ujs:submit-button", null) setData(element, "ujs:submit-button-formmethod", null) setData(element, "ujs:submit-button-formaction", null) } else if (matches(element, buttonClickSelector) || matches(element, inputChangeSelector)) { method = element.getAttribute("data-method") url = element.getAttribute("data-url") data = serializeElement(element, element.getAttribute("data-params")) } else { method = element.getAttribute("data-method") url = rails.href(element) data = element.getAttribute("data-params") } ajax({ type: method || "GET", url, data, dataType, // stopping the "ajax:beforeSend" event will cancel the ajax request beforeSend(xhr, options) { if (fire(element, "ajax:beforeSend", [xhr, options])) { return fire(element, "ajax:send", [xhr]) } else { fire(element, "ajax:stopped") return false } }, success(...args) { return fire(element, "ajax:success", args) }, error(...args) { return fire(element, "ajax:error", args) }, complete(...args) { return fire(element, "ajax:complete", args) }, crossDomain: isCrossDomain(url), withCredentials: (withCredentials != null) && (withCredentials !== "false") }) stopEverything(e)
}
const formSubmitButtonClick = function(e) {
const button = this const { form } = button if (!form) { return } // Register the pressed submit button if (button.name) { setData(form, "ujs:submit-button", {name: button.name, value: button.value}) } // Save attributes from button setData(form, "ujs:formnovalidate-button", button.formNoValidate) setData(form, "ujs:submit-button-formaction", button.getAttribute("formaction")) return setData(form, "ujs:submit-button-formmethod", button.getAttribute("formmethod"))
}
const preventInsignificantClick = function(e) {
const link = this const method = (link.getAttribute("data-method") || "GET").toUpperCase() const data = link.getAttribute("data-params") const metaClick = e.metaKey || e.ctrlKey const insignificantMetaClick = metaClick && (method === "GET") && !data const nonPrimaryMouseClick = (e.button != null) && (e.button !== 0) if (nonPrimaryMouseClick || insignificantMetaClick) { e.stopImmediatePropagation() }
}
export { handleRemoteWithRails, formSubmitButtonClick, preventInsignificantClick }