diff --git a/vendor/magento/module-bundle/ViewModel/ValidateQuantity.php b/vendor/magento/module-bundle/ViewModel/ValidateQuantity.php new file mode 100644 index 000000000000..ee7e2064e906 --- /dev/null +++ b/vendor/magento/module-bundle/ViewModel/ValidateQuantity.php @@ -0,0 +1,43 @@ +serializer = $serializer; + } + + /** + * Returns quantity validator. + * + * @return string + */ + public function getQuantityValidators(): string + { + $validators['validate-item-quantity'] = []; + + return $this->serializer->serialize($validators); + } +} diff --git a/vendor/magento/module-bundle/view/base/web/js/price-bundle.js b/vendor/magento/module-bundle/view/base/web/js/price-bundle.js index 207a97c270ee..5b72327dc740 100644 --- a/vendor/magento/module-bundle/view/base/web/js/price-bundle.js +++ b/vendor/magento/module-bundle/view/base/web/js/price-bundle.js @@ -22,9 +22,9 @@ define([ priceBoxSelector: '.price-box', optionHandlers: {}, optionTemplate: '<%- data.label %>' + - '<% if (data.finalPrice.value) { %>' + - ' +<%- data.finalPrice.formatted %>' + - '<% } %>', + '<% if (data.finalPrice.value) { %>' + + ' +<%- data.finalPrice.formatted %>' + + '<% } %>', controlContainer: 'dd', // should be eliminated priceFormat: {}, isFixedPrice: false, @@ -107,12 +107,15 @@ define([ changes = defaultGetOptionValue(bundleOption, this.options.optionConfig);//eslint-disable-line } - if (changes) { - priceBox.trigger('updatePrice', changes); - } + // eslint-disable-next-line no-use-before-define + if (isValidQty(bundleOption)) { + if (changes) { + priceBox.trigger('updatePrice', changes); + } - this._displayTierPriceBlock(bundleOption); - this.updateProductSummary(); + this._displayTierPriceBlock(bundleOption); + this.updateProductSummary(); + } }, /** @@ -132,7 +135,10 @@ define([ .selections[field.data('optionValueId')]; optionConfig.qty = field.val(); - optionInstance.trigger('change'); + // eslint-disable-next-line no-use-before-define + if (isValidQty(optionInstance)) { + optionInstance.trigger('change'); + } } }, @@ -373,6 +379,23 @@ define([ return changes; } + /** + * Check the quantity field if negative value occurs. + * + * @param {Object} bundleOption + */ + function isValidQty(bundleOption) { + var isValid = true, + qtyElem = bundleOption.data('qtyField'), + bundleOptionType = bundleOption.prop('type'); + + if (['radio', 'select-one'].includes(bundleOptionType) && qtyElem.val() < 0) { + isValid = false; + } + + return isValid; + } + /** * Helper to toggle qty field * @param {jQuery} element diff --git a/vendor/magento/module-bundle/view/frontend/layout/catalog_product_view_type_bundle.xml b/vendor/magento/module-bundle/view/frontend/layout/catalog_product_view_type_bundle.xml index d12f2e8f6a95..d816abfa9d10 100644 --- a/vendor/magento/module-bundle/view/frontend/layout/catalog_product_view_type_bundle.xml +++ b/vendor/magento/module-bundle/view/frontend/layout/catalog_product_view_type_bundle.xml @@ -32,12 +32,14 @@ \Magento\Bundle\Block\DataProviders\OptionPriceRenderer + Magento\Bundle\ViewModel\ValidateQuantity \Magento\Bundle\Block\DataProviders\OptionPriceRenderer + Magento\Bundle\ViewModel\ValidateQuantity @@ -49,7 +51,7 @@ - + diff --git a/vendor/magento/module-bundle/view/frontend/templates/catalog/product/view/type/bundle/option/radio.phtml b/vendor/magento/module-bundle/view/frontend/templates/catalog/product/view/type/bundle/option/radio.phtml index 11ed226c176c..706b28049470 100644 --- a/vendor/magento/module-bundle/view/frontend/templates/catalog/product/view/type/bundle/option/radio.phtml +++ b/vendor/magento/module-bundle/view/frontend/templates/catalog/product/view/type/bundle/option/radio.phtml @@ -3,13 +3,17 @@ * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ +use Magento\Bundle\ViewModel\ValidateQuantity; ?> getOption(); ?> getSelections(); ?> getDefaultSelection(); ?> getDefaultValues(); ?> - +getData('validateQuantityViewModel'); +?>