From 105813edbc58bfa1119d6f3f69340279001a2e8c Mon Sep 17 00:00:00 2001 From: Sascha Karnatz <122262394+sascha-karnatz@users.noreply.github.com> Date: Mon, 16 Oct 2023 11:16:23 +0200 Subject: [PATCH] Fix duplicated flatpickr calendar - DOM elements The datepicker is initialized multiple times, because the type attribute is reserved and had a side effect that triggered two times during the initialization. The datepicker now destroys the flatpickr instance, when the component will be removed from the DOM. --- app/helpers/alchemy/admin/base_helper.rb | 2 +- .../alchemy_admin/components/datepicker.js | 19 +++++--- .../alchemy/admin/styleguide/index.html.erb | 6 +-- .../helpers/alchemy/admin/base_helper_spec.rb | 6 +-- .../components/datepicker.spec.js | 44 ++++++++++++++----- .../ingredients/datetime_editor_spec.rb | 2 +- 6 files changed, 56 insertions(+), 23 deletions(-) diff --git a/app/helpers/alchemy/admin/base_helper.rb b/app/helpers/alchemy/admin/base_helper.rb index def3d722b6..52d45ea7d7 100644 --- a/app/helpers/alchemy/admin/base_helper.rb +++ b/app/helpers/alchemy/admin/base_helper.rb @@ -325,7 +325,7 @@ def alchemy_datepicker(object, method, html_options = {}) input_field = text_field object.class.name.demodulize.underscore.to_sym, method.to_sym, {type: "text", class: type, value: value}.merge(html_options) - content_tag("alchemy-datepicker", input_field, type: type) + content_tag("alchemy-datepicker", input_field, "input-type" => type) end # Render a hint icon with tooltip for given object. diff --git a/app/javascript/alchemy_admin/components/datepicker.js b/app/javascript/alchemy_admin/components/datepicker.js index 3c6617b1a6..df20bf6e80 100644 --- a/app/javascript/alchemy_admin/components/datepicker.js +++ b/app/javascript/alchemy_admin/components/datepicker.js @@ -4,7 +4,12 @@ import flatpickr from "flatpickr" class Datepicker extends AlchemyHTMLElement { static properties = { - type: { default: "date" } + inputType: { default: "date" } + } + + constructor() { + super() + this.flatpickr = undefined } afterRender() { @@ -12,18 +17,22 @@ class Datepicker extends AlchemyHTMLElement { // alchemy_i18n supports `zh_CN` etc., but flatpickr only has two-letter codes (`zh`) locale: currentLocale().slice(0, 2), altInput: true, - altFormat: translate(`formats.${this.type}`), + altFormat: translate(`formats.${this.inputType}`), altInputClass: "flatpickr-input", dateFormat: "Z", - enableTime: /time/.test(this.type), - noCalendar: this.type === "time", + enableTime: /time/.test(this.inputType), + noCalendar: this.inputType === "time", time_24hr: translate("formats.time_24hr"), onValueUpdate(_selectedDates, _dateStr, instance) { Alchemy.setElementDirty(instance.element.closest(".element-editor")) } } - flatpickr(this.getElementsByTagName("input")[0], options) + this.flatpickr = flatpickr(this.getElementsByTagName("input")[0], options) + } + + disconnected() { + this.flatpickr.destroy() } } diff --git a/app/views/alchemy/admin/styleguide/index.html.erb b/app/views/alchemy/admin/styleguide/index.html.erb index f841091919..ad7d516e83 100644 --- a/app/views/alchemy/admin/styleguide/index.html.erb +++ b/app/views/alchemy/admin/styleguide/index.html.erb @@ -73,7 +73,7 @@