diff --git a/addons/sale/static/src/js/product_configurator_mixin.js b/addons/sale/static/src/js/product_configurator_mixin.js index 1a74764aacc..0d49a4f245e 100644 --- a/addons/sale/static/src/js/product_configurator_mixin.js +++ b/addons/sale/static/src/js/product_configurator_mixin.js @@ -183,7 +183,7 @@ var ProductConfiguratorMixin = { */ triggerVariantChange: function ($container) { var self = this; - $container.find('ul[data-attribute_exclusions]').trigger('change'); + $container.find('ul[data-attribute_exclusions]').trigger('change', {$container: $container}); $container.find('input.js_variant_change:checked, select.js_variant_change').each(function () { self.handleCustomValues($(this)); }); @@ -559,14 +559,16 @@ var ProductConfiguratorMixin = { _updateProductImage: function ($productContainer, productId, productTemplateId) { var model = productId ? 'product.product' : 'product.template'; var modelId = productId || productTemplateId; - var imageSrc = '/web/image/{0}/{1}/image' + var imageUrl = '/web/image/{0}/{1}/' + (this._productImageField ? this._productImageField : 'image'); + var imageSrc = imageUrl .replace("{0}", model) .replace("{1}", modelId); var imagesSelectors = [ 'span[data-oe-model^="product."][data-oe-type="image"] img:first', 'img.product_detail_img', - 'span.variant_image img' + 'span.variant_image img', + 'img.variant_image', ]; var $img = $productContainer.find(imagesSelectors.join(', ')); diff --git a/addons/sale/static/src/js/product_configurator_modal.js b/addons/sale/static/src/js/product_configurator_modal.js index 630774b8da5..60544ada7c4 100644 --- a/addons/sale/static/src/js/product_configurator_modal.js +++ b/addons/sale/static/src/js/product_configurator_modal.js @@ -69,9 +69,9 @@ var OptionalProductsModal = Dialog.extend(ServicesMixin, ProductConfiguratorMixi this.dialogClass = 'oe_optional_products_modal' + (params.isWebsite ? ' oe_website_sale' : ''); if (this.isWebsite) { - delete this.events['change [data-attribute_exclusions]']; delete this.events['click button.js_add_cart_json']; } + this._productImageField = 'image_medium'; }, /** * @override @@ -440,7 +440,17 @@ var OptionalProductsModal = Dialog.extend(ServicesMixin, ProductConfiguratorMixi delete optionalProductsMap[optionId]; } }, + /** + * @override + */ + _onChangeCombination:function (ev, $parent, combination) { + $parent + .find('.td-product_name .product-name') + .first() + .text(combination.display_name); + ProductConfiguratorMixin._onChangeCombination.apply(this, arguments); + }, /** * When the quantity of the root product is updated, we need to update * the quantity of all the selected optional products. diff --git a/addons/sale_management/static/tests/product_configurator_advanced_test_ui.js b/addons/sale_management/static/tests/product_configurator_advanced_test_ui.js index 1cccd7fe0e1..074da95f06e 100644 --- a/addons/sale_management/static/tests/product_configurator_advanced_test_ui.js +++ b/addons/sale_management/static/tests/product_configurator_advanced_test_ui.js @@ -3,6 +3,8 @@ odoo.define('sale.sale_product_configurator_advanced_tour', function (require) { var tour = require('web_tour.tour'); +var optionVariantImage; + tour.register('sale_product_configurator_advanced_tour', { url: "/web", test: true, @@ -95,6 +97,25 @@ tour.register('sale_product_configurator_advanced_tour', { trigger: '.main_product div:contains("PA8: PAV1")', extra_trigger: '.oe_optional_products_modal', run: function () {} //check +}, { + trigger: '.oe_optional_products_modal .js_product:eq(1) div:contains("Conference Chair (Steel)")', + run: function () { + optionVariantImage = $('.oe_optional_products_modal .js_product:eq(1) img.variant_image').attr('src'); + } +}, { + trigger: '.oe_optional_products_modal .js_product:eq(1) input[data-value_name="Aluminium"]', +}, { + trigger: '.oe_optional_products_modal .js_product:eq(1) div:contains("Conference Chair (Aluminium)")', + run: function () { + var newVariantImage = $('.oe_optional_products_modal .js_product:eq(1) img.variant_image').attr('src'); + if (newVariantImage !== optionVariantImage) { + $('
').text('image variant option src changed').insertAfter('.oe_optional_products_modal .js_product:eq(1) .product-name'); + } + + } +}, { + extra_trigger: '.oe_optional_products_modal .js_product:eq(1) div:contains("image variant option src changed")', + trigger: '.oe_optional_products_modal .js_product:eq(1) input[data-value_name="Steel"]', }, { trigger: 'button span:contains(Confirm)', extra_trigger: '.oe_optional_products_modal', diff --git a/addons/website_sale/static/src/js/website_sale.js b/addons/website_sale/static/src/js/website_sale.js index ed03f81c5de..87f91a5b045 100644 --- a/addons/website_sale/static/src/js/website_sale.js +++ b/addons/website_sale/static/src/js/website_sale.js @@ -152,6 +152,8 @@ sAnimations.registry.WebsiteSale = sAnimations.Class.extend(ProductConfiguratorM 'change #shipping_use_same': '_onChangeShippingUseSame', 'click .toggle_summary': '_onToggleSummary', 'click input.js_product_change': 'onChangeVariant', + // dirty fix: prevent options modal events to be triggered and bubbled + 'change oe_optional_products_modal [data-attribute_exclusions]': 'onChangeVariant', }, /** @@ -589,6 +591,20 @@ sAnimations.registry.WebsiteSale = sAnimations.Class.extend(ProductConfiguratorM _onChangeShippingUseSame: function (ev) { $('.ship_to_other').toggle(!$(ev.currentTarget).prop('checked')); }, + /** + * @override + * + * Dirty fix: prevent options modal events to be triggered and bubbled + */ + onChangeVariant: function (ev, data) { + var $originPath = ev.originalEvent && Array.isArray(ev.originalEvent.path) ? $(ev.originalEvent.path) : $(); + var $container = data && data.$container ? data.$container : $(); + if ($originPath.add($container).hasClass('oe_optional_products_modal')) { + ev.stopPropagation(); + return; + } + return ProductConfiguratorMixin.onChangeVariant.apply(this, arguments); + }, /** * @private */ diff --git a/addons/website_sale/static/src/js/website_sale_tour_shop_custom_attribute_value.js b/addons/website_sale/static/src/js/website_sale_tour_shop_custom_attribute_value.js index 0a3b3b19f0c..87883f81172 100644 --- a/addons/website_sale/static/src/js/website_sale_tour_shop_custom_attribute_value.js +++ b/addons/website_sale/static/src/js/website_sale_tour_shop_custom_attribute_value.js @@ -4,6 +4,8 @@ odoo.define("website_sale.tour_shop_custom_attribute_value", function (require) var tour = require("web_tour.tour"); var base = require("web_editor.base"); + var optionVariantImage; + tour.register("shop_custom_attribute_value", { url: "/shop?search=Customizable Desk", test: true, @@ -34,6 +36,24 @@ odoo.define("website_sale.tour_shop_custom_attribute_value", function (require) }, { trigger: 'span.oe_price span:contains(600)', run: function (){}, // check + }, { + trigger: '.oe_optional_products_modal .js_product:eq(1) div:contains("Conference Chair (Steel)")', + run: function () { + optionVariantImage = $('.oe_optional_products_modal .js_product:eq(1) img.variant_image').attr('src'); + } + }, { + trigger: '.oe_optional_products_modal .js_product:eq(1) input[data-value_name="Aluminium"]', + }, { + trigger: '.oe_optional_products_modal .js_product:eq(1) div:contains("Conference Chair (Aluminium)")', + run: function () { + var newVariantImage = $('.oe_optional_products_modal .js_product:eq(1) img.variant_image').attr('src'); + if (newVariantImage !== optionVariantImage) { + $('
').text('image variant option src changed').insertAfter('.oe_optional_products_modal .js_product:eq(1) .product-name'); + } + } + }, { + extra_trigger: '.oe_optional_products_modal .js_product:eq(1) div:contains("image variant option src changed")', + trigger: '.oe_optional_products_modal .js_product:eq(1) input[data-value_name="Steel"]', }, { trigger: 'li.js_attribute_value span:contains(Aluminium)', extra_trigger: '.oe_optional_products_modal',