diff --git a/promotions/app/javascript/backend/solidus_promotions/controllers/product_option_values_controller.js b/promotions/app/javascript/backend/solidus_promotions/controllers/product_option_values_controller.js index 3b8f0c9fbe8..ebf0d1b442b 100644 --- a/promotions/app/javascript/backend/solidus_promotions/controllers/product_option_values_controller.js +++ b/promotions/app/javascript/backend/solidus_promotions/controllers/product_option_values_controller.js @@ -6,8 +6,6 @@ export default class extends Controller { connect() { this.wrapperClass = this.data.get("wrapperClass") || "promo-condition-option-value"; - - this.element.querySelectorAll("." + this.wrapperClass).forEach((element) => this.buildSelects(element)) } add_row(event) { @@ -15,7 +13,6 @@ export default class extends Controller { var content = this.templateTarget.innerHTML; this.linksTarget.insertAdjacentHTML("beforebegin", content); - this.buildSelects(this.linksTarget.previousElementSibling) } propagate_product_id_to_value_input(event) { @@ -24,7 +21,9 @@ export default class extends Controller { // we first need to greedily match all other square brackets const regEx = /(\[.*\])\[.*?\]$/; let wrapper = event.target.closest("." + this.wrapperClass); - let optionValuesInput = wrapper.querySelector(".option-values-select[type='hidden']"); + let optionValuesInput = wrapper.querySelector("[is=option-value-picker]"); + optionValuesInput.dataset.productId = event.target.value; + optionValuesInput.value = ""; optionValuesInput.name = optionValuesInput.name.replace( regEx, `$1[${event.target.value}]` @@ -37,26 +36,4 @@ export default class extends Controller { let wrapper = event.target.closest("." + this.wrapperClass); wrapper.remove(); } - - // helper functions - - buildSelects(wrapper) { - let productSelect = wrapper.querySelector(".product-select") - let optionValueSelect = wrapper.querySelector(".option-values-select[type='hidden']") - this.buildProductSelect(productSelect) - $(optionValueSelect).optionValueAutocomplete({ productSelect }); - } - - buildProductSelect(productSelect) { - var jQueryProductSelect = $(productSelect) - jQueryProductSelect.productAutocomplete({ - multiple: false, - }) - // capture the jQuery "change" event and re-emit it as DOM event "select2Change" - // so that Stimulus can capture it - jQueryProductSelect.on('change', function () { - let event = new Event('select2Change', { bubbles: true }) // fire a native event - productSelect.dispatchEvent(event); - }); - } } diff --git a/promotions/app/javascript/backend/solidus_promotions/web_components/option_value_picker.js b/promotions/app/javascript/backend/solidus_promotions/web_components/option_value_picker.js index a5f7d0489a9..6e384a994ae 100644 --- a/promotions/app/javascript/backend/solidus_promotions/web_components/option_value_picker.js +++ b/promotions/app/javascript/backend/solidus_promotions/web_components/option_value_picker.js @@ -1,11 +1,9 @@ $.fn.optionValueAutocomplete = function (options) { - 'use strict'; + "use strict"; // Default options - options = options || {} - var multiple = typeof(options['multiple']) !== 'undefined' ? options['multiple'] : true; - var productSelect = options['productSelect']; - + options = options || {}; + var multiple = typeof options["multiple"] !== "undefined" ? options["multiple"] : true; function formatOptionValue(option_value) { return Select2.util.escapeMarkup(option_value.name); } @@ -14,39 +12,58 @@ $.fn.optionValueAutocomplete = function (options) { minimumInputLength: 3, multiple: multiple, initSelection: function (element, callback) { - $.get(Spree.pathFor('api/option_values'), { - ids: element.val().split(','), - token: Spree.api_key - }, function (data) { - callback(multiple ? data : data[0]); - }); + $.get( + Spree.pathFor("api/option_values"), + { + ids: element.val().split(","), + token: Spree.api_key, + }, + function (data) { + callback(multiple ? data : data[0]); + } + ); }, ajax: { - url: Spree.pathFor('api/option_values'), - datatype: 'json', + url: Spree.pathFor("api/option_values"), + datatype: "json", data: function (term, page) { - var productId = typeof(productSelect) !== 'undefined' ? $(productSelect).select2('val') : null; + var productId = this[0].dataset.productId; return { q: { name_cont: term, - variants_product_id_eq: productId + variants_product_id_eq: productId, }, - token: Spree.api_key + token: Spree.api_key, }; }, results: function (data, page) { return { results: data }; - } + }, }, formatResult: formatOptionValue, - formatSelection: formatOptionValue + formatSelection: formatOptionValue, }); }; class OptionValuePicker extends HTMLInputElement { connectedCallback() { $(this).optionValueAutocomplete(); + + this.observer = new MutationObserver((muts) => { + for (const m of muts) { + if (m.attributeName.startsWith("data-product-id")) { + this.restart(); + } + } + }); + + this.observer.observe(this, { attributes: true }); + } + + restart() { + $(this).select2("destroy"); + $(this).optionValueAutocomplete(); } } -customElements.define('option-value-picker', OptionValuePicker, { extends: 'input' }); +customElements.define("option-value-picker", OptionValuePicker, { extends: "input" }); diff --git a/promotions/app/javascript/backend/solidus_promotions/web_components/product_picker.js b/promotions/app/javascript/backend/solidus_promotions/web_components/product_picker.js index 02cc58e6840..576fd60f68e 100644 --- a/promotions/app/javascript/backend/solidus_promotions/web_components/product_picker.js +++ b/promotions/app/javascript/backend/solidus_promotions/web_components/product_picker.js @@ -1,6 +1,11 @@ class ProductPicker extends HTMLInputElement { connectedCallback() { - $(this).productAutocomplete(); + const multiple = this.dataset.multiple !== "false"; + $(this).productAutocomplete({ multiple }); + $(this).on("change", (_) => { + let event = new Event('select2Change', { bubbles: true }) // fire a native event + this.dispatchEvent(event) + }) } } diff --git a/promotions/lib/views/backend/solidus_promotions/admin/condition_fields/_line_item_option_value.html.erb b/promotions/lib/views/backend/solidus_promotions/admin/condition_fields/_line_item_option_value.html.erb index 59d8818c1b4..17a51dfab4c 100644 --- a/promotions/lib/views/backend/solidus_promotions/admin/condition_fields/_line_item_option_value.html.erb +++ b/promotions/lib/views/backend/solidus_promotions/admin/condition_fields/_line_item_option_value.html.erb @@ -5,19 +5,20 @@