mirror of
https://github.com/openfoodfoundation/openfoodnetwork
synced 2026-03-01 02:03:22 +00:00
Add variant controller
This will manage the various unit fields. Maybe it should have a more specific name.
This commit is contained in:
@@ -61,12 +61,12 @@
|
||||
|
||||
- product.variants.each_with_index do |variant, variant_index|
|
||||
= form.fields_for("products][#{product_index}][variants_attributes][", variant, index: variant_index) do |variant_form|
|
||||
%tr.condensed
|
||||
%tr.condensed{ 'data-controller': "variant" }
|
||||
= render partial: 'variant_row', locals: { variant:, f: variant_form }
|
||||
|
||||
= form.fields_for("products][#{product_index}][variants_attributes][NEW_RECORD", product.variants.build) do |new_variant_form|
|
||||
%template{ 'data-nested-form-target': "template" }
|
||||
%tr.condensed
|
||||
%tr.condensed{ 'data-controller': "variant" }
|
||||
= render partial: 'variant_row', locals: { variant: new_variant_form.object, f: new_variant_form }
|
||||
|
||||
%tr{ 'data-nested-form-target': "target" }
|
||||
|
||||
@@ -32,5 +32,7 @@ export default class ProductController extends Controller {
|
||||
this.variantUnit.value = variant_unit_with_scale;
|
||||
this.variantUnitScale.value = "";
|
||||
}
|
||||
this.variantUnit.dispatchEvent(new Event("change"));
|
||||
this.variantUnitScale.dispatchEvent(new Event("change"));
|
||||
}
|
||||
}
|
||||
|
||||
63
app/webpacker/controllers/variant_controller.js
Normal file
63
app/webpacker/controllers/variant_controller.js
Normal file
@@ -0,0 +1,63 @@
|
||||
import { Controller } from "stimulus";
|
||||
|
||||
// Dynamically update related variant fields
|
||||
//
|
||||
export default class VariantController extends Controller {
|
||||
connect() {
|
||||
// Assuming these will be available on the variant soon, just a quick hack to find the product fields:
|
||||
const product = this.element.closest("[data-record-id]");
|
||||
this.variantUnit = product.querySelector('[name$="[variant_unit]"]');
|
||||
this.variantUnitScale = product.querySelector('[name$="[variant_unit_scale]"]');
|
||||
this.variantUnitName = product.querySelector('[name$="[variant_unit_name]"]');
|
||||
|
||||
this.unitValueWithDescription = this.element.querySelector(
|
||||
'[name$="[unit_value_with_description]"]',
|
||||
);
|
||||
this.displayAs = this.element.querySelector('[name$="[display_as]"]');
|
||||
this.unitToDisplay = this.element.querySelector('[name$="[unit_to_display]"]');
|
||||
|
||||
// on unit changed; update display_as:placeholder and unit_to_display
|
||||
[this.variantUnit, this.variantUnitScale, this.variantUnitName].forEach((element) => {
|
||||
element.addEventListener("change", this.#unitChanged.bind(this), { passive: true });
|
||||
});
|
||||
|
||||
// on unit_value_with_description changed; update unit_value and unit_description
|
||||
// on unit_value and/or unit_description changed; update display_as:placeholder and unit_to_display
|
||||
this.unitValueWithDescription.addEventListener("input", this.#unitValueChanged.bind(this), {
|
||||
passive: true,
|
||||
});
|
||||
|
||||
// on display_as changed; update unit_to_display (how does this relate to unit_presentation?)
|
||||
this.displayAs.addEventListener("input", this.#updateUnitDisplay.bind(this), { passive: true });
|
||||
}
|
||||
|
||||
disconnect() {
|
||||
// Make sure to clean up anything that happened outside
|
||||
}
|
||||
|
||||
// private
|
||||
|
||||
// Extract variant_unit and variant_unit_scale from dropdown variant_unit_with_scale,
|
||||
// and update hidden product fields
|
||||
#unitChanged(event) {
|
||||
//todo: deduplicate events.
|
||||
//Hmm in hindsight the logic in product_controller should be inn this controller already. then we can do everything in one event, and store the generated name in an instance variable.
|
||||
this.#updateUnitDisplay();
|
||||
}
|
||||
|
||||
// Extract unit_value and unit_description from unit_value_with_description,
|
||||
// and update hidden fields
|
||||
#unitValueChanged(event) {
|
||||
//todo: deduplicate events.
|
||||
this.#updateUnitDisplay();
|
||||
}
|
||||
|
||||
// Update display_as placeholder and unit_to_display
|
||||
#updateUnitDisplay() {
|
||||
// const unitDisplay = OptionValueNamer...
|
||||
const unitDisplay =
|
||||
this.unitValueWithDescription.value + " " + (this.variantUnitName.value || "~g"); //To Remove: DEMO only
|
||||
this.displayAs.placeholder = unitDisplay;
|
||||
this.unitToDisplay.textContent = this.displayAs.value || unitDisplay;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user