diff --git a/app/assets/javascripts/alchemy/alchemy.confirm_dialog.js.coffee b/app/assets/javascripts/alchemy/alchemy.confirm_dialog.js.coffee index f8e3834689..4cc930e2ca 100644 --- a/app/assets/javascripts/alchemy/alchemy.confirm_dialog.js.coffee +++ b/app/assets/javascripts/alchemy/alchemy.confirm_dialog.js.coffee @@ -31,7 +31,6 @@ class window.Alchemy.ConfirmDialog extends Alchemy.Dialog @cancel_button.focus() @cancel_button.click => @close() - Alchemy.Buttons.enable() false @ok_button.click => @close() diff --git a/app/assets/javascripts/alchemy/alchemy.dialog.js.coffee b/app/assets/javascripts/alchemy/alchemy.dialog.js.coffee index 1449e25ec5..cac43df8a7 100644 --- a/app/assets/javascripts/alchemy/alchemy.dialog.js.coffee +++ b/app/assets/javascripts/alchemy/alchemy.dialog.js.coffee @@ -109,9 +109,6 @@ class window.Alchemy.Dialog # Watches ajax requests inside of dialog body and replaces the content accordingly watch_remote_forms: -> form = $('[data-remote="true"]', @dialog_body) - form.bind "ajax:complete", () => - Alchemy.Buttons.enable(@dialog_body) - return form.bind "ajax:success", (event) => xhr = event.detail[2] content_type = xhr.getResponseHeader('Content-Type') diff --git a/app/assets/javascripts/alchemy/alchemy.element_editors.js.coffee b/app/assets/javascripts/alchemy/alchemy.element_editors.js.coffee index b8874d8c8f..0f42efa547 100644 --- a/app/assets/javascripts/alchemy/alchemy.element_editors.js.coffee +++ b/app/assets/javascripts/alchemy/alchemy.element_editors.js.coffee @@ -175,7 +175,6 @@ Alchemy.ElementEditors = # Prevent this event from beeing called twice on the same element if event.currentTarget == event.target Alchemy.setElementClean($element) - Alchemy.Buttons.enable($element) true # Toggle visibility of the ingredient fields in the group diff --git a/app/javascript/alchemy_admin.js b/app/javascript/alchemy_admin.js index 0483dfc517..af6c13e5b3 100644 --- a/app/javascript/alchemy_admin.js +++ b/app/javascript/alchemy_admin.js @@ -1,7 +1,6 @@ import "@hotwired/turbo-rails" import Rails from "@rails/ujs" -import Buttons from "alchemy_admin/buttons" import GUI from "alchemy_admin/gui" import { translate } from "alchemy_admin/i18n" import Dirty from "alchemy_admin/dirty" @@ -21,6 +20,7 @@ import PagePublicationFields from "alchemy_admin/page_publication_fields" $.fx.speeds._default = 400 // Web Components +import "alchemy_admin/components/button" import "alchemy_admin/components/char_counter" import "alchemy_admin/components/datepicker" import "alchemy_admin/components/node_select" @@ -41,7 +41,6 @@ if (typeof window.Alchemy === "undefined") { // Enhance the global Alchemy object with imported features Object.assign(Alchemy, { - Buttons, ...Dirty, GUI, t: translate, // Global utility method for translating a given string diff --git a/app/javascript/alchemy_admin/buttons.js b/app/javascript/alchemy_admin/buttons.js deleted file mode 100644 index c4bd574810..0000000000 --- a/app/javascript/alchemy_admin/buttons.js +++ /dev/null @@ -1,62 +0,0 @@ -function observe(scope) { - $("form", scope) - .not(".button_with_label form") - .on("submit", function (event) { - const $form = $(this) - const $btn = $form.find(":submit") - const $outside_button = $( - `[data-alchemy-button][form="${$form.attr("id")}"]` - ) - - const isDisabled = - $btn.attr("disabled") === "disabled" || - $outside_button.attr("disabled") === "disabled" - - if (isDisabled) { - event.preventDefault() - event.stopPropagation() - } else { - disable($btn) - if ($outside_button) { - disable($outside_button) - } - } - }) -} - -function disable(button) { - const $button = $(button) - const spinner = new Alchemy.Spinner("small") - $button.data("content", $button.html()) - $button.attr("disabled", true) - $button.attr("tabindex", "-1") - $button.addClass("disabled") - $button.css({ - width: $button.outerWidth(), - height: $button.outerHeight() - }) - $button.empty() - spinner.spin($button) -} - -function enable(scope) { - const $buttons = $( - "form :submit:disabled, [data-alchemy-button].disabled", - scope - ) - $.each($buttons, function () { - const $button = $(this) - $button.removeClass("disabled") - $button.removeAttr("disabled") - $button.removeAttr("tabindex") - $button.css("width", "") - $button.css("height", "") - $button.html($button.data("content")) - }) -} - -export default { - observe, - disable, - enable -} diff --git a/app/javascript/alchemy_admin/components/button.js b/app/javascript/alchemy_admin/components/button.js new file mode 100644 index 0000000000..8a2c1db3a7 --- /dev/null +++ b/app/javascript/alchemy_admin/components/button.js @@ -0,0 +1,52 @@ +import Spinner from "../spinner" + +class Button extends HTMLButtonElement { + connectedCallback() { + if (this.form) { + this.form.addEventListener("submit", (event) => { + const isDisabled = this.getAttribute("disabled") === "disabled" + + if (isDisabled) { + event.preventDefault() + event.stopPropagation() + } else { + this.disable() + } + }) + + if (this.form.dataset.remote == "true") { + this.form.addEventListener("ajax:complete", () => { + this.enable() + }) + } + } else { + console.warn("No form for button found!", this) + } + } + + disable() { + const spinner = new Spinner("small") + const rect = this.getBoundingClientRect() + + this.dataset.initialButtonText = this.innerHTML + this.setAttribute("disabled", "disabled") + this.setAttribute("tabindex", "-1") + this.classList.add("disabled") + this.style.width = `${rect.width}px` + this.style.height = `${rect.height}px` + this.innerHTML = " " + + spinner.spin(this) + } + + enable() { + this.classList.remove("disabled") + this.removeAttribute("disabled") + this.removeAttribute("tabindex") + this.style.width = null + this.style.height = null + this.innerHTML = this.dataset.initialButtonText + } +} + +customElements.define("alchemy-button", Button, { extends: "button" }) diff --git a/app/javascript/alchemy_admin/gui.js b/app/javascript/alchemy_admin/gui.js index 64c2504f9b..fcc0b2991a 100644 --- a/app/javascript/alchemy_admin/gui.js +++ b/app/javascript/alchemy_admin/gui.js @@ -1,7 +1,6 @@ import TagsAutocomplete from "alchemy_admin/tags_autocomplete" function init(scope) { - Alchemy.Buttons.observe(scope) if (!scope) { Alchemy.watchForDialogs() } diff --git a/app/views/alchemy/admin/elements/_add_nested_element_form.html.erb b/app/views/alchemy/admin/elements/_add_nested_element_form.html.erb index 6f49ce4b79..7e53ab3134 100644 --- a/app/views/alchemy/admin/elements/_add_nested_element_form.html.erb +++ b/app/views/alchemy/admin/elements/_add_nested_element_form.html.erb @@ -1,7 +1,7 @@ <%= content_tag :div, class: 'add-nested-element', data: { element_id: element.id } do %> <% if element.expanded? || element.fixed? %> - <% if element.nestable_elements.length == 1 && - (nestable_element = element.nestable_elements.first) && + <% if element.nestable_elements.length == 1 && + (nestable_element = element.nestable_elements.first) && Alchemy::Element.all_from_clipboard_for_parent_element(get_clipboard("elements"), element).none? %> <%= form_for [:admin, Alchemy::Element.new(name: nestable_element)], @@ -9,7 +9,7 @@ <%= f.hidden_field :name %> <%= f.hidden_field :page_version_id, value: element.page_version_id %> <%= f.hidden_field :parent_element_id, value: element.id %> -
<% end %> -