mirror of
https://github.com/openfoodfoundation/openfoodnetwork
synced 2026-02-10 23:07:47 +00:00
Show popout on click or down key
It looks like a select drop-down, so it can behave like one too.
This commit is contained in:
@@ -85,10 +85,10 @@
|
||||
%td.field
|
||||
= variant_form.text_field :price, 'aria-label': t('admin.products_page.columns.price'), value: number_to_currency(variant.price, unit: '')&.strip # TODO: add a spec to prove that this formatting is necessary. If so, it should be in a shared form helper for currency inputs
|
||||
= error_message_on variant, :price
|
||||
%td.field.on-hand__wrapper
|
||||
%button.on-hand__button
|
||||
%td.field.on-hand__wrapper{'data-controller': "popout"}
|
||||
%button.on-hand__button{'data-popout-target': "button"}
|
||||
= variant.on_demand ? t(:on_demand) : variant.on_hand
|
||||
%div.on-hand__popout
|
||||
%div.on-hand__popout{ style: 'display: none;', 'data-popout-target': "dialog"}
|
||||
.field
|
||||
= variant_form.number_field :on_hand, 'aria-label': t('admin.products_page.columns.on_hand')
|
||||
= error_message_on variant, :on_hand
|
||||
|
||||
26
app/webpacker/controllers/popout_controller.js
Normal file
26
app/webpacker/controllers/popout_controller.js
Normal file
@@ -0,0 +1,26 @@
|
||||
import { Controller } from "stimulus";
|
||||
|
||||
// Allows a form section to "pop out" and show additional options
|
||||
export default class PopoutController extends Controller {
|
||||
static targets = ["button", "dialog"];
|
||||
|
||||
connect() {
|
||||
this.first_input = this.dialogTarget.querySelector("input");
|
||||
|
||||
// Show when click or down-arrow on button
|
||||
this.buttonTarget.addEventListener("click", this.show.bind(this));
|
||||
this.buttonTarget.addEventListener("keydown", this.showIfDownArrow.bind(this));
|
||||
}
|
||||
|
||||
show(e) {
|
||||
this.dialogTarget.style.display = "block";
|
||||
this.first_input.focus();
|
||||
e.preventDefault();
|
||||
}
|
||||
|
||||
showIfDownArrow(e) {
|
||||
if (e.keyCode == 40) {
|
||||
this.show(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -327,7 +327,6 @@
|
||||
}
|
||||
|
||||
&__popout {
|
||||
display: none;
|
||||
position: absolute;
|
||||
top: -1em;
|
||||
left: -1em;
|
||||
|
||||
49
spec/javascripts/stimulus/popout_controller_test.js
Normal file
49
spec/javascripts/stimulus/popout_controller_test.js
Normal file
@@ -0,0 +1,49 @@
|
||||
/**
|
||||
* @jest-environment jsdom
|
||||
*/
|
||||
|
||||
import { Application } from "stimulus";
|
||||
import popout_controller from "../../../app/webpacker/controllers/popout_controller";
|
||||
|
||||
describe("PopoutController", () => {
|
||||
beforeAll(() => {
|
||||
const application = Application.start();
|
||||
application.register("popout", popout_controller);
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
document.body.innerHTML = `
|
||||
<div data-controller="popout">
|
||||
<button id="button" data-popout-target="button">On demand</button>
|
||||
<div id="dialog" data-popout-target="dialog" style="display: none;">
|
||||
<input id="input1">
|
||||
<input id="input2">
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
const button = document.getElementById("button");
|
||||
const input1 = document.getElementById("input1");
|
||||
const input2 = document.getElementById("input2");
|
||||
});
|
||||
|
||||
describe("Show", () => {
|
||||
it("shows the dialog on click", () => {
|
||||
button.click();
|
||||
|
||||
expect(dialog.style.display).toBe("block"); // visible
|
||||
});
|
||||
|
||||
it("shows the dialog on keyboard down arrow", () => {
|
||||
button.dispatchEvent(new KeyboardEvent("keydown", { keyCode: 40 }));
|
||||
|
||||
expect(dialog.style.display).toBe("block"); // visible
|
||||
});
|
||||
|
||||
it("doesn't show the dialog on other key press (tab)", () => {
|
||||
button.dispatchEvent(new KeyboardEvent("keydown", { keyCode: 9 }));
|
||||
|
||||
expect(dialog.style.display).toBe("none"); // not visible
|
||||
});
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user