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 @@
- +
@@ -83,12 +83,12 @@
- +
- +
diff --git a/spec/helpers/alchemy/admin/base_helper_spec.rb b/spec/helpers/alchemy/admin/base_helper_spec.rb index 3d3bb0e98b..5590104ff7 100644 --- a/spec/helpers/alchemy/admin/base_helper_spec.rb +++ b/spec/helpers/alchemy/admin/base_helper_spec.rb @@ -126,14 +126,14 @@ module Alchemy let(:type) { nil } it "renders a text field with data attribute for 'date'" do - is_expected.to have_selector("alchemy-datepicker[type='date'] input[type='text']") + is_expected.to have_selector("alchemy-datepicker[input-type='date'] input[type='text']") end context "when datetime given as type" do let(:type) { :datetime } it "renders a text field with data attribute for 'datetime'" do - is_expected.to have_selector("alchemy-datepicker[type='datetime'] input[type='text']") + is_expected.to have_selector("alchemy-datepicker[input-type='datetime'] input[type='text']") end end @@ -141,7 +141,7 @@ module Alchemy let(:type) { :time } it "renders a text field with data attribute for 'time'" do - is_expected.to have_selector("alchemy-datepicker[type='time'] input[type='text']") + is_expected.to have_selector("alchemy-datepicker[input-type='time'] input[type='text']") end end diff --git a/spec/javascript/alchemy_admin/components/datepicker.spec.js b/spec/javascript/alchemy_admin/components/datepicker.spec.js index 25d9716217..2279ca6685 100644 --- a/spec/javascript/alchemy_admin/components/datepicker.spec.js +++ b/spec/javascript/alchemy_admin/components/datepicker.spec.js @@ -19,19 +19,43 @@ describe("alchemy-datepicker", () => { component = renderComponent("alchemy-datepicker", html) }) - it("should render the input field", () => { - expect(component.getElementsByTagName("input")[0]).toBeInstanceOf( - HTMLElement - ) + describe("picker without type", () => { + it("should render the input field", () => { + expect(component.getElementsByTagName("input")[0]).toBeInstanceOf( + HTMLElement + ) + }) + + it("should enhance the input field with a flat picker config", () => { + expect(component.getElementsByTagName("input")[0].className).toEqual( + "flatpickr-input" + ) + }) + + it("should have a type attribute", () => { + expect(component.inputType).toEqual("date") + }) + + it("creates a flatpickr-calendar on opening", () => { + expect(document.querySelector(".flatpickr-calendar")).toBeInstanceOf( + HTMLElement + ) + }) }) - it("should enhance the input field with a flat picker config", () => { - expect(component.getElementsByTagName("input")[0].className).toEqual( - "flatpickr-input" - ) + describe("with type attribute", () => { + it("creates only one flatpickr-calendar on opening", () => { + component.setAttribute("inputType", "datetime") + expect( + document.getElementsByClassName("flatpickr-calendar").length + ).toEqual(1) + }) }) - it("should have a type attribute", () => { - expect(component.type).toEqual("date") + describe("remove datepicker", () => { + it("removes the flatpickr-calendar after removing", () => { + component.remove() + expect(document.querySelector(".flatpickr-calendar")).toBeNull() + }) }) }) diff --git a/spec/views/alchemy/ingredients/datetime_editor_spec.rb b/spec/views/alchemy/ingredients/datetime_editor_spec.rb index 3b5b7426fc..3dd9e13cc3 100644 --- a/spec/views/alchemy/ingredients/datetime_editor_spec.rb +++ b/spec/views/alchemy/ingredients/datetime_editor_spec.rb @@ -17,6 +17,6 @@ it "renders a datepicker" do render element_editor - expect(rendered).to have_css('alchemy-datepicker[type="date"] input[type="text"].date') + expect(rendered).to have_css('alchemy-datepicker[input-type="date"] input[type="text"].date') end end