mirror of
https://github.com/openfoodfoundation/openfoodnetwork
synced 2026-02-27 01:43:22 +00:00
Replace inline JS for toggling order cycle advanced settings with StimulusJs controller
Partially addresses #8699. This adjusts the Stimulus toggle controller so you can toggle content in both directions via a single element. This is in addition to the previous behaviour for toggling via multiple elements like radio buttons when each element always toggles in one direction only. If a toggle element contains a chevron icon this will automatically toggle the direction of that icon too. Note, in order to not have to re-implement the animation provided by the slideToggle() function in standard JavaScript, this just switches the style :display between 'none' and 'block' so it is not as smooth. Perhaps it could be made more smooth later with a CSS transition.
This commit is contained in:
@@ -1,19 +1,9 @@
|
||||
- content_for :wrapper_data_controllers, "toggle"
|
||||
- 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()' }
|
||||
%button#toggle_settings{ "data-action": "toggle#toggle" }
|
||||
= t('.advanced_settings')
|
||||
%i.icon-chevron-down
|
||||
|
||||
#advanced_settings{ hidden: true }
|
||||
#advanced_settings{ "data-toggle-target": "content", style: "display: none" }
|
||||
= render partial: "/admin/order_cycles/advanced_settings"
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
= render "layouts/i18n_script"
|
||||
= yield :stripe_js
|
||||
|
||||
#wrapper{ data: { hook: '' } }
|
||||
#wrapper{ data: { hook: '', controller: (yield :wrapper_data_controllers) } }
|
||||
.flash-container
|
||||
- if flash[:error]
|
||||
.flash.error= flash[:error]
|
||||
|
||||
@@ -4,9 +4,22 @@ export default class extends Controller {
|
||||
static targets = ["content"];
|
||||
|
||||
toggle(event) {
|
||||
event.stopImmediatePropagation()
|
||||
const input = event.currentTarget;
|
||||
const chevron = input.querySelector(".icon-chevron-down, .icon-chevron-up")
|
||||
const toggleViaSingleElement = !input.dataset.toggleShow;
|
||||
|
||||
if(chevron) {
|
||||
chevron.classList.toggle("icon-chevron-down");
|
||||
chevron.classList.toggle("icon-chevron-up");
|
||||
}
|
||||
|
||||
this.contentTargets.forEach((t) => {
|
||||
t.style.display = input.dataset.toggleShow === "true" ? "block" : "none";
|
||||
if(toggleViaSingleElement) {
|
||||
t.style.display = t.style.display === "none" ? "block" : "none";
|
||||
} else {
|
||||
t.style.display = input.dataset.toggleShow === "true" ? "block" : "none";
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,9 +9,17 @@ describe("ToggleController", () => {
|
||||
describe("#toggle", () => {
|
||||
beforeEach(() => {
|
||||
document.body.innerHTML = `<div data-controller="toggle">
|
||||
<span id="button" data-action="click->toggle#toggle" data-toggle-show="true" />
|
||||
<div id="content" data-toggle-target="content" >
|
||||
content
|
||||
<button id="toggle" data-action="click->toggle#toggle"></button>
|
||||
<button id="toggle-show" data-action="click->toggle#toggle" data-toggle-show="true"></button>
|
||||
<button id="toggle-hide" data-action="click->toggle#toggle" data-toggle-show="false"></button>
|
||||
<button id="toggle-with-chevron" data-action="click->toggle#toggle">
|
||||
<i class="icon-chevron-down"></i>
|
||||
</button>
|
||||
<div id="visible-content" data-toggle-target="content" style="display: block;">
|
||||
visible content
|
||||
</div>
|
||||
<div id="invisible-content" data-toggle-target="content" style="display: none;">
|
||||
invisible content
|
||||
</div>
|
||||
</div>`;
|
||||
|
||||
@@ -19,14 +27,73 @@ describe("ToggleController", () => {
|
||||
application.register("toggle", toggle_controller);
|
||||
});
|
||||
|
||||
it("toggle the content", () => {
|
||||
const button = document.getElementById("button");
|
||||
const content = document.getElementById("content");
|
||||
expect(content.style.display).toBe("");
|
||||
it("toggling a button which shows and hides content switches the visibility of content", () => {
|
||||
const button = document.getElementById("toggle");
|
||||
const invisibleContent = document.getElementById("invisible-content");
|
||||
const visibleContent = document.getElementById("visible-content");
|
||||
expect(invisibleContent.style.display).toBe("none");
|
||||
expect(visibleContent.style.display).toBe("block");
|
||||
|
||||
button.click();
|
||||
|
||||
expect(content.style.display).toBe("block");
|
||||
expect(invisibleContent.style.display).toBe("block");
|
||||
expect(visibleContent.style.display).toBe("none");
|
||||
});
|
||||
|
||||
it("toggling a button with 'data-toggle-show=true' shows invisible content", () => {
|
||||
const button = document.getElementById("toggle-show");
|
||||
const invisibleContent = document.getElementById("invisible-content");
|
||||
expect(invisibleContent.style.display).toBe("none");
|
||||
|
||||
button.click();
|
||||
|
||||
expect(invisibleContent.style.display).toBe("block");
|
||||
});
|
||||
|
||||
it("toggling a button with 'data-toggle-show=true' doesn't hide visible content", () => {
|
||||
const button = document.getElementById("toggle-show");
|
||||
const visibleContent = document.getElementById("visible-content");
|
||||
expect(visibleContent.style.display).toBe("block");
|
||||
|
||||
button.click();
|
||||
|
||||
expect(visibleContent.style.display).toBe("block");
|
||||
});
|
||||
|
||||
it("toggling a button with 'data-toggle-show=false' hides visible content", () => {
|
||||
const button = document.getElementById("toggle-hide");
|
||||
const visibleContent = document.getElementById("visible-content");
|
||||
expect(visibleContent.style.display).toBe("block");
|
||||
|
||||
button.click();
|
||||
|
||||
expect(visibleContent.style.display).toBe("none");
|
||||
});
|
||||
|
||||
it("toggling a button with 'data-toggle-show=false' doesn't show invisible content", () => {
|
||||
const button = document.getElementById("toggle-hide");
|
||||
const invisibleContent = document.getElementById("invisible-content");
|
||||
expect(invisibleContent.style.display).toBe("none");
|
||||
|
||||
button.click();
|
||||
|
||||
expect(invisibleContent.style.display).toBe("none");
|
||||
});
|
||||
|
||||
it("toggling a button with a chevron icon switches the visibility of content and the direction of the icon", () => {
|
||||
const buttonA = document.getElementById("toggle-with-chevron");
|
||||
const chevron = buttonA.querySelector("i");
|
||||
const invisibleContent = document.getElementById("invisible-content");
|
||||
const visibleContent = document.getElementById("visible-content");
|
||||
expect(invisibleContent.style.display).toBe("none");
|
||||
expect(visibleContent.style.display).toBe("block");
|
||||
expect(chevron.className).toBe("icon-chevron-down");
|
||||
|
||||
buttonA.click();
|
||||
|
||||
expect(invisibleContent.style.display).toBe("block");
|
||||
expect(visibleContent.style.display).toBe("none");
|
||||
expect(chevron.className).toBe("icon-chevron-up");
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user