I am trying to disable a swatch, once after it has been selected. So it should not be deselected...
How to do it in Magento2.2.x ?
Magento Stack Exchange is a question and answer site for users of the Magento e-Commerce platform. It only takes a minute to sign up.
Sign up to join this communityI managed to stop the swatch being unselected by overriding part of the core swatch-renderer.js. I use Amasty's Color Swatches Pro so I made the change to the swatch-renderer.js in that module.
I copied the widget...
_OnClick: function ($this, $widget) {
and changed this section...
if ($this.hasClass('selected')) {
// COMMENT OUT THE 3 LINES BELOW TO PREVENT TOGGLING OF CURRENT SWATCH SELECTION
//$parent.removeAttr('option-selected').find('.selected').removeClass('selected');
//$input.val('');
//$label.text('');
} else {
$parent.attr('option-selected', $this.attr('option-id')).find('.selected').removeClass('selected');
$label.text($this.attr('option-label'));
$input.val($this.attr('option-id'));
$this.addClass('selected');
}
You could do this with modifications to the swatch-renderer.js
. Adding a couple of lines of code to the _OnClick
event within here like below will disable pointer events and drop the opacity so the user knows it's disabled:
$this.parent().css("pointer-events","none");
$this.parent().css("opacity","0.6");
I would prefer to do this with a mixin which wraps the original function to maintain all original functionality from the call and only minor additional functionality is added.
Create a new JS file to override the default _OnClick
method within swatch-renderer.js
. You could put this in your theme or module. Here i have put it within a theme.
define([
'jquery',
'mage/utils/wrapper'
], function ($, wrapper) {
'use strict';
return function(swatchRenderer){
var OnClickWrapper = wrapper.wrap(swatchRenderer.prototype._OnClick, function(originalSwatchRenderer){
var result = originalSwatchRenderer();
/*Custom code start*/
$(arguments[1][0]).parent().css({"pointer-events":"none","opacity":"0.6"});
/*Custom code end*/
return result;
});
swatchRenderer.prototype._OnClick = OnClickWrapper;
return swatchRenderer;
};
});
app/design/frontend/ThemeVendor/ThemeName/Magento_Swatches/web/js/swatch-renderer-mixin.js
Add a requirejs-config.js
file to initalise the new mixin file:
var config = {
config: {
mixins: {
'Magento_Swatches/js/swatch-renderer': {
'Magento_Swatches/js/swatch-renderer-mixin': true
}
}
}
};
app/design/frontend/ThemeVendor/ThemeName/Magento_Swatches/requirejs-config.js
\magento\app\code\Module\RewriteSwatches\etc\module.xml
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd">
<module name="Module_RewriteSwatches" setup_version="2.0.1">
</module>
\magento\app\code\Module\RewriteSwatches\view\frontend\requirejs-config.js
var config = {
config: {
mixins: {
'Magento_Swatches/js/swatch-renderer': {
'Module_RewriteSwatches/js/swatch-renderer': true
}
}
}};
\magento\app\code\Module\RewriteSwatches\registration.php
<?php \Magento\Framework\Component\ComponentRegistrar::register(\Magento\Framework\Component\ComponentRegistrar::MODULE,'Module_RewriteSwatches',__DIR__);
\magento\app\code\Module\RewriteSwatches\view\frontend\web\js\swatch-renderer.js
define([
'jquery'
], function ($) {
'use strict';
return function (widget) {
$.widget('mage.SwatchRenderer', widget, {
/**
* Event for swatch options
*
* @param {Object} $this
* @param {Object} $widget
* @param {String|undefined} eventName
* @private
*/
_OnClick: function ($this, $widget, eventName) {
var $parent = $this.parents('.' + $widget.options.classes.attributeClass),
$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);
if ($widget.inProductList) {
$input = $widget.productForm.find(
'.' + $widget.options.classes.attributeInput + '[name="super_attribute[' + attributeId + ']"]'
);
}
if ($this.hasClass('disabled')) {
return;
}
if ($this.hasClass('selected')) {
//$parent.removeAttr('option-selected').find('.selected').removeClass('selected');
//$input.val('');
//$label.text('');
//$this.attr('aria-checked', false);
} else {
$parent.attr('option-selected', $this.attr('option-id')).find('.selected').removeClass('selected');
$label.text($this.attr('option-label'));
$input.val($this.attr('option-id'));
$input.attr('data-attr-name', this._getAttributeCodeById(attributeId));
$this.addClass('selected');
$widget._toggleCheckedAttributes($this, $wrapper);
}
$widget._Rebuild();
if ($widget.element.parents($widget.options.selectorProduct)
.find(this.options.selectorProductPrice).is(':data(mage-priceBox)')
) {
$widget._UpdatePrice();
}
$(document).trigger('updateMsrpPriceBlock',
[
parseInt($this.attr('index'), 10) + 1,
$widget.options.jsonConfig.optionPrices
]);
$widget._loadMedia(eventName);
$input.trigger('change');
}
});
return $.mage.SwatchRenderer;
}
});