The question:
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 ?
The Solutions:
Below are the methods you can try. The first solution is probably the best. Try others if the first one doesn’t work. Senior developers aren’t just copying/pasting – they read the methods carefully & apply them wisely to each case.
Method 1
I 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');
}
Method 2
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 Mixin to Overide Swatch Rendering
-
Create a new JS file to override the default
_OnClick
method withinswatch-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
Method 3
magentoappcodeModuleRewriteSwatchesetcmodule.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>
magentoappcodeModuleRewriteSwatchesviewfrontendrequirejs-config.js
var config = {
config: {
mixins: {
'Magento_Swatches/js/swatch-renderer': {
'Module_RewriteSwatches/js/swatch-renderer': true
}
}
}};
magentoappcodeModuleRewriteSwatchesregistration.php
<?php MagentoFrameworkComponentComponentRegistrar::register(MagentoFrameworkComponentComponentRegistrar::MODULE,'Module_RewriteSwatches',__DIR__);
magentoappcodeModuleRewriteSwatchesviewfrontendwebjsswatch-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;
}
});
All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0