diff --git a/app/views/admin/products_v3/_product_row.html.haml b/app/views/admin/products_v3/_product_row.html.haml index 9a874d591a..1b4f4c4148 100644 --- a/app/views/admin/products_v3/_product_row.html.haml +++ b/app/views/admin/products_v3/_product_row.html.haml @@ -9,14 +9,14 @@ %td.field = f.text_field :sku, 'aria-label': t('admin.products_page.columns.sku') = error_message_on product, :sku -%td.field +%td.field{ 'data-controller': 'toggle-control', 'data-toggle-control-match-value': 'items' } = f.select :variant_unit_with_scale, options_for_select(WeightsAndMeasures.variant_unit_options, product.variant_unit_with_scale), {}, class: "fullwidth no-input", 'aria-label': t('admin.products_page.columns.unit_scale'), - data: { "controller": "tom-select", "tom-select-options-value": '{ "plugins": [] }' } - = f.text_field :variant_unit_name, 'aria-label': t('items') + data: { "controller": "tom-select", "tom-select-options-value": '{ "plugins": [] }', action: "change->toggle-control#displayIfMatch"} + = f.text_field :variant_unit_name, 'aria-label': t('items'), 'data-toggle-control-target': 'control', style: (product.variant_unit == "items" ? "" : "display: none") %td.align-right -# empty %td.align-right diff --git a/app/webpacker/controllers/toggle_control_controller.js b/app/webpacker/controllers/toggle_control_controller.js index 8c65af417f..6beea90ec2 100644 --- a/app/webpacker/controllers/toggle_control_controller.js +++ b/app/webpacker/controllers/toggle_control_controller.js @@ -8,7 +8,7 @@ import { Controller } from "stimulus"; // export default class extends Controller { static targets = ["control", "content", "chevron"]; - static values = { selector: String }; + static values = { selector: String, match: String }; disableIfPresent(event) { const present = !!this.#inputValue(event.currentTarget); // Coerce value to boolean @@ -43,6 +43,13 @@ export default class extends Controller { element.style.display = element.style.display === "none" ? "block" : "none"; } + // Display the control if selected value matches value in data-toggle-match="" + displayIfMatch(event) { + const inputValue = this.#inputValue(event.currentTarget); + + this.#toggleDisplay(inputValue == this.matchValue); + } + // private #toggleDisabled(disable) { @@ -56,6 +63,17 @@ export default class extends Controller { } } + #toggleDisplay(show) { + this.controlTargets.forEach((target) => { + target.style.display = (show ? "block" : "none"); + }); + + // Focus first when displayed + if (show) { + this.controlTargets[0].focus(); + } + } + // Return input's value, but only if it would be submitted by a form // Radio buttons not supported (yet) #inputValue(input) { diff --git a/spec/javascripts/stimulus/toggle_control_controller_test.js b/spec/javascripts/stimulus/toggle_control_controller_test.js index 412ec9e7ee..dca6e3df0e 100644 --- a/spec/javascripts/stimulus/toggle_control_controller_test.js +++ b/spec/javascripts/stimulus/toggle_control_controller_test.js @@ -61,6 +61,7 @@ describe("ToggleControlController", () => { }); }); }); + describe("#enableIfPresent", () => { describe("with input", () => { beforeEach(() => { @@ -88,6 +89,35 @@ describe("ToggleControlController", () => { }); }); }); + + describe("#displayIfMatch", () => { + describe("with select", () => { + beforeEach(() => { + document.body.innerHTML = `
+ + +
`; + }); + + it("Shows when match is selected", () => { + select.value = "items" + select.dispatchEvent(new Event("change")); + + expect(control.style.display).toBe("block"); + }); + + it("Hides when match is not selected", () => { + select.value = "weight_1" + select.dispatchEvent(new Event("change")); + + expect(control.style.display).toBe("none"); + }); + }); + }); + describe("#toggleDisplay", () => { beforeEach(() => { document.body.innerHTML = `
@@ -108,6 +138,7 @@ describe("ToggleControlController", () => { expect(content.style.display).toBe("block"); }); }); + describe("#toggleAdvancedSettings", () => { beforeEach(() => { document.body.innerHTML = `