From 05756616dd8d514640aabacf7fb298ee6f516115 Mon Sep 17 00:00:00 2001 From: Cillian O'Ruanaidh Date: Fri, 4 Feb 2022 12:23:24 +0000 Subject: [PATCH] Add a remote-toggle controller that can toggle elements outside of its scope This is instead of adding the :data-controller attribute to the div#wrapper because that will wrap pretty much all content on the admin pages. Co-authored-by: Matt-Yorkley <9029026+Matt-Yorkley@users.noreply.github.com> --- .../_order_cycle_top_buttons.html.haml | 19 ++---- .../controllers/remote_toggle_controller.js | 17 ++++++ .../stimulus/remote_toggle_controller_test.js | 58 +++++++++++++++++++ 3 files changed, 79 insertions(+), 15 deletions(-) create mode 100644 app/webpacker/controllers/remote_toggle_controller.js create mode 100644 spec/javascripts/stimulus/remote_toggle_controller_test.js diff --git a/app/views/admin/order_cycles/_order_cycle_top_buttons.html.haml b/app/views/admin/order_cycles/_order_cycle_top_buttons.html.haml index 86ca6b2ae4..2cc89117b0 100644 --- a/app/views/admin/order_cycles/_order_cycle_top_buttons.html.haml +++ b/app/views/admin/order_cycles/_order_cycle_top_buttons.html.haml @@ -1,19 +1,8 @@ - content_for :page_actions do - :javascript - function toggleSettings(){ - if( $('#advanced_settings').is(":visible") ){ - $('button#toggle_settings i').switchClass("icon-chevron-up","icon-chevron-down") - } - else { - $('button#toggle_settings i').switchClass("icon-chevron-down","icon-chevron-up") - } - $("#advanced_settings").slideToggle() - } - - %li - %button#toggle_settings{ onClick: 'toggleSettings()' } + %li{ "data-controller": "remote-toggle", "data-remote-toggle-selector-value": "#advanced_settings" } + %button#toggle_settings{ "data-action": "click->remote-toggle#toggle" } = t('.advanced_settings') - %i.icon-chevron-down + %i.icon-chevron-down{ "data-remote-toggle-target": "chevron" } -#advanced_settings{ hidden: true } +#advanced_settings{ style: "display: none" } = render partial: "/admin/order_cycles/advanced_settings" diff --git a/app/webpacker/controllers/remote_toggle_controller.js b/app/webpacker/controllers/remote_toggle_controller.js new file mode 100644 index 0000000000..25006d8651 --- /dev/null +++ b/app/webpacker/controllers/remote_toggle_controller.js @@ -0,0 +1,17 @@ +import { Controller } from "stimulus"; + +export default class extends Controller { + static targets = ["chevron"]; + static values = { selector: String } + + toggle(event) { + if (this.hasChevronTarget) { + this.chevronTarget.classList.toggle("icon-chevron-down") + this.chevronTarget.classList.toggle("icon-chevron-up") + } + + const element = document.querySelector(this.selectorValue) + element.style.display = element.style.display === "none" ? "block" : "none" + } +} + diff --git a/spec/javascripts/stimulus/remote_toggle_controller_test.js b/spec/javascripts/stimulus/remote_toggle_controller_test.js new file mode 100644 index 0000000000..e46a0b61fe --- /dev/null +++ b/spec/javascripts/stimulus/remote_toggle_controller_test.js @@ -0,0 +1,58 @@ +/** + * @jest-environment jsdom + */ + +import { Application } from "stimulus"; +import remote_toggle_controller from "../../../app/webpacker/controllers/remote_toggle_controller"; + +describe("RemoteToggleController", () => { + describe("#toggle", () => { + beforeEach(() => { + document.body.innerHTML = ` +
+ + +
+
...
+ `; + + const application = Application.start(); + application.register("remote-toggle", remote_toggle_controller); + }); + + it("clicking a toggle switches the visibility of the :data-remote-toggle-selector element", () => { + const button = document.getElementById("remote-toggle"); + const content = document.getElementById("content"); + expect(content.style.display).toBe(""); + + button.click(); + + expect(content.style.display).toBe("none"); + + button.click(); + + expect(content.style.display).toBe("block"); + }); + + /* skipping, this test passes when it's the only test in this file but not otherwise? */ + it.skip("clicking a toggle with a chevron icon switches the visibility of content and the direction of the icon", () => { + const button = document.getElementById("remote-toggle-with-chevron"); + const chevron = button.querySelector("i"); + const content = document.getElementById("content"); + expect(content.style.display).toBe(""); + expect(chevron.className).toBe("icon-chevron-down"); + + button.click(); + + expect(content.style.display).toBe("none"); + expect(chevron.className).toBe("icon-chevron-up"); + + button.click(); + + expect(content.style.display).toBe("block"); + expect(chevron.className).toBe("icon-chevron-down"); + }); + }); +});