diff --git a/app/code/Magento/ConfigurableProduct/view/frontend/web/js/configurable.js b/app/code/Magento/ConfigurableProduct/view/frontend/web/js/configurable.js index ae564610e4b0b..4aeafd72aa8ee 100644 --- a/app/code/Magento/ConfigurableProduct/view/frontend/web/js/configurable.js +++ b/app/code/Magento/ConfigurableProduct/view/frontend/web/js/configurable.js @@ -26,9 +26,9 @@ define([ state: {}, priceFormat: {}, optionTemplate: '<%- data.label %>' + - '<% if (typeof data.finalPrice.value !== "undefined") { %>' + - ' <%- data.finalPrice.formatted %>' + - '<% } %>', + '<% if (typeof data.finalPrice.value !== "undefined") { %>' + + ' <%- data.finalPrice.formatted %>' + + '<% } %>', mediaGallerySelector: '[data-gallery-role=gallery-placeholder]', mediaGalleryInitial: null, slyOldPriceSelector: '.sly-old-price', @@ -123,8 +123,6 @@ define([ if (this.options.spConfig.inputsInitialized) { this._setValuesByAttribute(); } - - this._setInitialOptionsLabels(); }, /** @@ -160,18 +158,6 @@ define([ }, this)); }, - /** - * Set additional field with initial label to be used when switching between options with different prices. - * @private - */ - _setInitialOptionsLabels: function () { - $.each(this.options.spConfig.attributes, $.proxy(function (index, element) { - $.each(element.options, $.proxy(function (optIndex, optElement) { - this.options.spConfig.attributes[index].options[optIndex].initialLabel = optElement.label; - }, this)); - }, this)); - }, - /** * Set up .on('change') events for each option element to configure the option. * @private @@ -385,18 +371,13 @@ define([ prevConfig, index = 1, allowedProducts, - allowedProductsByOption, - allowedProductsAll, i, j, - finalPrice = parseFloat(this.options.spConfig.prices.finalPrice.amount), + basePrice = parseFloat(this.options.spConfig.prices.basePrice.amount), optionFinalPrice, optionPriceDiff, optionPrices = this.options.spConfig.optionPrices, - allowedOptions = [], - indexKey, - allowedProductMinPrice, - allowedProductsAllMinPrice; + allowedProductMinPrice; this._clearSelect(element); element.options[0] = new Option('', ''); @@ -408,61 +389,39 @@ define([ } if (options) { - for (indexKey in this.options.spConfig.index) { - /* eslint-disable max-depth */ - if (this.options.spConfig.index.hasOwnProperty(indexKey)) { - allowedOptions = allowedOptions.concat(_.values(this.options.spConfig.index[indexKey])); - } - } - - if (prevConfig) { - allowedProductsByOption = {}; - allowedProductsAll = []; + for (i = 0; i < options.length; i++) { + allowedProducts = []; + optionPriceDiff = 0; - for (i = 0; i < options.length; i++) { - /* eslint-disable max-depth */ + /* eslint-disable max-depth */ + if (prevConfig) { for (j = 0; j < options[i].products.length; j++) { // prevConfig.config can be undefined if (prevConfig.config && prevConfig.config.allowedProducts && prevConfig.config.allowedProducts.indexOf(options[i].products[j]) > -1) { - if (!allowedProductsByOption[i]) { - allowedProductsByOption[i] = []; - } - allowedProductsByOption[i].push(options[i].products[j]); - allowedProductsAll.push(options[i].products[j]); + allowedProducts.push(options[i].products[j]); } } - } - - if (typeof allowedProductsAll[0] !== 'undefined' && - typeof optionPrices[allowedProductsAll[0]] !== 'undefined') { - allowedProductsAllMinPrice = this._getAllowedProductWithMinPrice(allowedProductsAll); - finalPrice = parseFloat(optionPrices[allowedProductsAllMinPrice].finalPrice.amount); - } - } - - for (i = 0; i < options.length; i++) { - allowedProducts = prevConfig ? allowedProductsByOption[i] : options[i].products.slice(0); - optionPriceDiff = 0; - - if (typeof allowedProducts[0] !== 'undefined' && - typeof optionPrices[allowedProducts[0]] !== 'undefined') { - allowedProductMinPrice = this._getAllowedProductWithMinPrice(allowedProducts); - optionFinalPrice = parseFloat(optionPrices[allowedProductMinPrice].finalPrice.amount); - optionPriceDiff = optionFinalPrice - finalPrice; - options[i].label = options[i].initialLabel; - - if (optionPriceDiff !== 0) { - options[i].label += ' ' + priceUtils.formatPrice( - optionPriceDiff, - this.options.priceFormat, - true - ); + } else { + allowedProducts = options[i].products.slice(0); + + if (typeof allowedProducts[0] !== 'undefined' && + typeof optionPrices[allowedProducts[0]] !== 'undefined') { + allowedProductMinPrice = this._getAllowedProductWithMinPrice(allowedProducts); + optionFinalPrice = parseFloat(optionPrices[allowedProductMinPrice].finalPrice.amount); + optionPriceDiff = optionFinalPrice - basePrice; + + if (optionPriceDiff !== 0) { + options[i].label = options[i].label + ' ' + priceUtils.formatPrice( + optionPriceDiff, + this.options.priceFormat, + true); + } } } - if (allowedProducts.length > 0 || _.include(allowedOptions, options[i].id)) { + if (allowedProducts.length > 0) { options[i].allowedProducts = allowedProducts; element.options[index] = new Option(this._getOptionLabel(options[i]), options[i].id); @@ -470,16 +429,20 @@ define([ element.options[index].setAttribute('price', options[i].price); } - if (allowedProducts.length === 0) { - element.options[index].disabled = true; - } - element.options[index].config = options[i]; index++; } + if (i === 0) { + this.options.values[attributeId] = options[i].id; + } /* eslint-enable max-depth */ } + + if (window.location.href.indexOf('#') !== -1) { + this._parseQueryParams(window.location.href.substr(window.location.href.indexOf('#') + 1)); + } + } }, diff --git a/app/code/Magento/Swatches/view/frontend/web/js/swatch-renderer.js b/app/code/Magento/Swatches/view/frontend/web/js/swatch-renderer.js index 250141a942b10..78e569a862957 100644 --- a/app/code/Magento/Swatches/view/frontend/web/js/swatch-renderer.js +++ b/app/code/Magento/Swatches/view/frontend/web/js/swatch-renderer.js @@ -362,7 +362,7 @@ define([ isInProductView = false; productId = this.element.parents('.product-item-details') - .find('.price-box.price-final_price').attr('data-product-id'); + .find('.price-box.price-final_price').attr('data-product-id'); if (!productId) { // Check individual product. @@ -386,6 +386,8 @@ define([ container = this.element, classes = this.options.classes, chooseText = this.options.jsonConfig.chooseText, + selectedArray = []; // Variable declation for autoselect element array + showTooltip = this.options.showTooltip; $widget.optionsMap = {}; @@ -407,7 +409,7 @@ define([ if ($widget.options.enableControlLabel) { label += '' + - $('').text(item.label).html() + + item.label + '' + ''; } @@ -415,7 +417,7 @@ define([ if ($widget.inProductList) { $widget.productForm.append(input); input = ''; - listLabel = 'aria-label="' + $('').text(item.label).html() + '"'; + listLabel = 'aria-label="' + item.label + '"'; } else { listLabel = 'aria-labelledby="' + controlLabelId + '"'; } @@ -423,17 +425,17 @@ define([ // Create new control container.append( '
' + - label + - '
' + - options + select + - '
' + input + + 'attribute-code="' + item.code + '" ' + + 'attribute-id="' + item.id + '">' + + label + + '
' + + options + select + + '
' + input + '
' ); @@ -451,7 +453,14 @@ define([ }; } }); + //Create array for Autoselect swatch + selectedArray.push($widget.element.find('[attribute-id=' + item.id + '] .swatch-option')[0]); }); + // Connect Tooltip + container + .find('[option-type="1"], [option-type="2"], [option-type="0"], [option-type="3"]') + .SwatchRendererTooltip(); + if (showTooltip === 1) { // Connect Tooltip @@ -472,6 +481,14 @@ define([ //Emulate click on all swatches from Request $widget._EmulateSelected($.parseQuery()); $widget._EmulateSelected($widget._getSelectedAttributes()); + + //Trigger click for Autoselect first option swatch + $.each(selectedArray, function () { + if (this !== undefined) { + this.click(); + } + }); + }, /** @@ -519,12 +536,11 @@ define([ id = this.id; type = parseInt(optionConfig[id].type, 10); - value = optionConfig[id].hasOwnProperty('value') ? - $('').text(optionConfig[id].value).html() : ''; + value = optionConfig[id].hasOwnProperty('value') ? optionConfig[id].value : ''; thumb = optionConfig[id].hasOwnProperty('thumb') ? optionConfig[id].thumb : ''; width = _.has(sizeConfig, 'swatchThumb') ? sizeConfig.swatchThumb.width : 110; height = _.has(sizeConfig, 'swatchThumb') ? sizeConfig.swatchThumb.height : 90; - label = this.label ? $('').text(this.label).html() : ''; + label = this.label ? this.label : ''; attr = ' id="' + controlId + '-item-' + id + '"' + ' index="' + index + '"' + @@ -677,13 +693,13 @@ define([ */ _loadMedia: function () { var $main = this.inProductList ? - this.element.parents('.product-item-info') : - this.element.parents('.column.main'), + this.element.parents('.product-item-info') : + this.element.parents('.column.main'), images; if (this.options.useAjax) { this._debouncedLoadProductMedia(); - } else { + } else { images = this.options.jsonConfig.images[this.getProduct()]; if (!images) { @@ -700,7 +716,7 @@ define([ */ _sortImages: function (images) { return _.sortBy(images, function (image) { - return parseInt(image.position, 10); + return image.position; }); }, @@ -716,8 +732,7 @@ define([ $wrapper = $this.parents('.' + $widget.options.classes.attributeOptionsWrapper), $label = $parent.find('.' + $widget.options.classes.attributeSelectedOptionLabelClass), attributeId = $parent.attr('attribute-id'), - $input = $parent.find('.' + $widget.options.classes.attributeInput), - checkAdditionalData = JSON.parse(this.options.jsonSwatchConfig[attributeId]['additional_data']); + $input = $parent.find('.' + $widget.options.classes.attributeInput); if ($widget.inProductList) { $input = $widget.productForm.find( @@ -746,17 +761,19 @@ define([ $widget._Rebuild(); if ($widget.element.parents($widget.options.selectorProduct) - .find(this.options.selectorProductPrice).is(':data(mage-priceBox)') + .find(this.options.selectorProductPrice).is(':data(mage-priceBox)') ) { $widget._UpdatePrice(); } $(document).trigger('updateMsrpPriceBlock', [ - _.findKey($widget.options.jsonConfig.index, $widget.options.jsonConfig.defaultValues), + parseInt($this.attr('index'), 10) + 1, $widget.options.jsonConfig.optionPrices ]); + $widget._loadMedia(); + if (parseInt(checkAdditionalData['update_product_preview_image'], 10) === 1) { $widget._loadMedia(); } @@ -786,7 +803,7 @@ define([ */ _toggleCheckedAttributes: function ($this, $wrapper) { $wrapper.attr('aria-activedescendant', $this.attr('id')) - .find('.' + this.options.classes.optionClass).attr('aria-checked', false); + .find('.' + this.options.classes.optionClass).attr('aria-checked', false); $this.attr('aria-checked', true); }, @@ -933,10 +950,19 @@ define([ var $widget = this, $product = $widget.element.parents($widget.options.selectorProduct), $productPrice = $product.find(this.options.selectorProductPrice), - result = $widget._getNewPrices(), + options = _.object(_.keys($widget.optionsMap), {}), + result, tierPriceHtml, isShow; + $widget.element.find('.' + $widget.options.classes.attributeClass + '[option-selected]').each(function () { + var attributeId = $(this).attr('attribute-id'); + + options[attributeId] = $(this).attr('option-selected'); + }); + + result = $widget.options.jsonConfig.optionPrices[_.findKey($widget.options.jsonConfig.index, options)]; + $productPrice.trigger( 'updatePrice', { @@ -948,7 +974,7 @@ define([ $product.find(this.options.slyOldPriceSelector)[isShow ? 'show' : 'hide'](); - if (typeof result != 'undefined' && result.tierPrices && result.tierPrices.length) { + if (typeof result != 'undefined' && result.tierPrices.length) { if (this.options.tierPriceTemplate) { tierPriceHtml = mageTemplate( this.options.tierPriceTemplate, @@ -982,35 +1008,6 @@ define([ }.bind(this)); }, - /** - * Get new prices for selected options - * - * @returns {*} - * @private - */ - _getNewPrices: function () { - var $widget = this, - optionPriceDiff = 0, - allowedProduct = this._getAllowedProductWithMinPrice(this._CalcProducts()), - optionPrices = this.options.jsonConfig.optionPrices, - basePrice = parseFloat(this.options.jsonConfig.prices.basePrice.amount), - optionFinalPrice, - newPrices; - - if (!_.isEmpty(allowedProduct)) { - optionFinalPrice = parseFloat(optionPrices[allowedProduct].finalPrice.amount); - optionPriceDiff = optionFinalPrice - basePrice; - } - - if (optionPriceDiff !== 0) { - newPrices = this.options.jsonConfig.optionPrices[allowedProduct]; - } else { - newPrices = $widget.options.jsonConfig.prices; - } - - return newPrices; - }, - /** * Get prices * @@ -1020,11 +1017,27 @@ define([ * @private */ _getPrices: function (newPrices, displayPrices) { - var $widget = this; + var $widget = this, + optionPriceDiff = 0, + allowedProduct, optionPrices, basePrice, optionFinalPrice; if (_.isEmpty(newPrices)) { - newPrices = $widget._getNewPrices(); + allowedProduct = this._getAllowedProductWithMinPrice(this._CalcProducts()); + optionPrices = this.options.jsonConfig.optionPrices; + basePrice = parseFloat(this.options.jsonConfig.prices.basePrice.amount); + + if (!_.isEmpty(allowedProduct)) { + optionFinalPrice = parseFloat(optionPrices[allowedProduct].finalPrice.amount); + optionPriceDiff = optionFinalPrice - basePrice; + } + + if (optionPriceDiff !== 0) { + newPrices = this.options.jsonConfig.optionPrices[allowedProduct]; + } else { + newPrices = $widget.options.jsonConfig.prices; + } } + _.each(displayPrices, function (price, code) { if (newPrices[code]) { @@ -1237,8 +1250,8 @@ define([ updateBaseImage: function (images, context, isInProductView) { var justAnImage = images[0], initialImages = this.options.mediaGalleryInitial, - imagesToUpdate, gallery = context.find(this.options.mediaGallerySelector).data('gallery'), + imagesToUpdate, isInitial; if (isInProductView) {