Configurable product swatches not displayed disabled out when out of stock

In this article, we are going to fix the problem:

If the attribute is text swatch then out of stock products does not display as disabled in magento2.

Let’s follow the steps :-

Step 1: Enable “Display Out of Stock Products” settings

Login into the admin panel, Then Store -> Configuration -> Catalog -> Inventory and then

Display Out of Stock Products – Yes

 

 

Then Lets build the module to show out of stock options as disabled..

Step 2: Create and Declare the Module

Create the following folders in the magento project root directory (ex. – C:\xampp\htdocs\magento2):

  • app/code/Thecoachsmb
  • app/code/Thecoachsmb/OutOfSTockProducts

It is necessary to create app/code/Thecoachsmb/OutOfSTockProducts/etc folder and add theΒ module.xml file in it.

The content would be : –

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd">
<module name="Thecoachsmb_OutOfSTockProducts" > 
     <sequence> 
         <module name="Magento_Swatches"/> 
     </sequence>
 </module> 
</config>

Step 3: Registration of Module

To register the module, create aΒ registration.php file in the Β app/code/Thecoachsmb/OutOfSTockProducts

Contents would be:

<?php
\Magento\Framework\Component\ComponentRegistrar::register(
	\Magento\Framework\Component\ComponentRegistrar::MODULE,
	'Thecoachsmb_OutOfSTockProducts',
	__DIR__
);

Step 4: Extend the Js file

To register the module, create a requirejs-config.js file in the app/code/Thecoachsmb/OutOfSTockProducts/view/frontend/

Contents would be:

var config = {
    config: {
        mixins: {
            'Magento_Swatches/js/swatch-renderer': {
                'Thecoachsmb_OutOfSTockProducts/js/swatch-renderer-mixin': true
            }
        }
    }
};

Step 5: Show out of stock products in grey disabled

To register the module, create a swatch-renderer-mixin.js file in the app/code/Thecoachsmb/OutOfSTockProducts/view/frontend/web/js

Contents would be:

define([
  Β  'jquery'
], function ($) {
  Β  'use strict';
  Β  return function (widget) {
  Β  Β  Β  console.log('Hello from SwatchExtend');
  Β  Β  Β  $.widget('mage.SwatchRenderer', widget, {
  Β  Β  Β  Β  Β  _RenderSwatchOptions: function (config, controlId) {
  Β  Β  Β  Β  Β  Β  Β  var optionConfig = this.options.jsonSwatchConfig[config.id],
  Β  Β  Β  Β  Β  Β  Β  Β  Β  optionClass = this.options.classes.optionClass,
  Β  Β  Β  Β  Β  Β  Β  Β  Β  sizeConfig = this.options.jsonSwatchImageSizeConfig,
  Β  Β  Β  Β  Β  Β  Β  Β  Β  moreLimit = parseInt(this.options.numberToShow, 10),
  Β  Β  Β  Β  Β  Β  Β  Β  Β  moreClass = this.options.classes.moreButton,
  Β  Β  Β  Β  Β  Β  Β  Β  Β  moreText = this.options.moreButtonText,
  Β  Β  Β  Β  Β  Β  Β  Β  Β  salableId = this.options.jsonConfig.salable[config.id],
  Β  Β  Β  Β  Β  Β  Β  Β  Β  countAttributes = 0,
  Β  Β  Β  Β  Β  Β  Β  Β  Β  html = '';

Β  Β  Β  Β  Β  Β  Β  Β  if (!this.options.jsonSwatchConfig.hasOwnProperty(config.id)) {
  Β  Β  Β  Β  Β  Β  Β  Β  Β  return '';
  Β  Β  Β  Β  Β  Β  Β  }

Β  Β  Β  Β  Β  Β  Β  Β  $.each(config.options, function (index) {
  Β  Β  Β  Β  Β  Β  Β  Β  Β  var id,
  Β  Β  Β  Β  Β  Β  Β  Β  Β  Β  Β  type,
  Β  Β  Β  Β  Β  Β  Β  Β  Β  Β  Β  value,
  Β  Β  Β  Β  Β  Β  Β  Β  Β  Β  Β  thumb,
  Β  Β  Β  Β  Β  Β  Β  Β  Β  Β  Β  label,
  Β  Β  Β  Β  Β  Β  Β  Β  Β  Β  Β  width,
  Β  Β  Β  Β  Β  Β  Β  Β  Β  Β  Β  height,
  Β  Β  Β  Β  Β  Β  Β  Β  Β  Β  Β  attr,
  Β  Β  Β  Β  Β  Β  Β  Β  Β  Β  Β  swatchImageWidth,
  Β  Β  Β  Β  Β  Β  Β  Β  Β  Β  Β  swatchImageHeight;
  Β  Β  Β  Β  Β  Β  Β  Β  Β  if (!optionConfig.hasOwnProperty(this.id)) {
  Β  Β  Β  Β  Β  Β  Β  Β  Β  Β  Β  return '';
  Β  Β  Β  Β  Β  Β  Β  Β  Β  }

Β  Β  Β  Β  Β  Β  Β  Β  Β  Β  // Add more button
  Β  Β  Β  Β  Β  Β  Β  Β  Β  if (moreLimit === countAttributes++) {
  Β  Β  Β  Β  Β  Β  Β  Β  Β  Β  Β  html += '<a href="#" class="' + moreClass + '"><span>' + moreText + '</span></a>';
  Β  Β  Β  Β  Β  Β  Β  Β  Β  }

Β  Β  Β  Β  Β  Β  Β  Β  Β  Β  id = this.id;
  Β  Β  Β  Β  Β  Β  Β  Β  Β  type = parseInt(optionConfig[id].type, 10);
  Β  Β  Β  Β  Β  Β  Β  Β  Β  value = optionConfig[id].hasOwnProperty('value') ?
  Β  Β  Β  Β  Β  Β  Β  Β  Β  Β  Β  $('<i></i>').text(optionConfig[id].value).html() : '';

Β  Β  Β  Β  Β  Β  Β  Β  Β  Β  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 ? $('<i></i>').text(this.label).html() : '';

Β  Β  Β  Β  Β  Β  Β  Β  Β  Β  attr =
  Β  Β  Β  Β  Β  Β  Β  Β  Β  Β  Β  ' id="' + controlId + '-item-' + id + '"' +
  Β  Β  Β  Β  Β  Β  Β  Β  Β  Β  Β  ' index="' + index + '"' +
  Β  Β  Β  Β  Β  Β  Β  Β  Β  Β  Β  ' aria-checked="false"' +
  Β  Β  Β  Β  Β  Β  Β  Β  Β  Β  Β  ' aria-describedby="' + controlId + '"' +
  Β  Β  Β  Β  Β  Β  Β  Β  Β  Β  Β  ' tabindex="0"' +
  Β  Β  Β  Β  Β  Β  Β  Β  Β  Β  Β  ' data-option-type="' + type + '"' +
  Β  Β  Β  Β  Β  Β  Β  Β  Β  Β  Β  ' data-option-id="' + id + '"' +
  Β  Β  Β  Β  Β  Β  Β  Β  Β  Β  Β  ' data-option-label="' + label + '"' +
  Β  Β  Β  Β  Β  Β  Β  Β  Β  Β  Β  ' aria-label="' + label + '"' +
  Β  Β  Β  Β  Β  Β  Β  Β  Β  Β  Β  ' role="option"' +
  Β  Β  Β  Β  Β  Β  Β  Β  Β  Β  Β  ' data-thumb-width="' + width + '"' +
  Β  Β  Β  Β  Β  Β  Β  Β  Β  Β  Β  ' data-thumb-height="' + height + '"';

Β  Β  Β  Β  Β  Β  Β  Β  Β  Β  attr += thumb !== '' ? ' data-option-tooltip-thumb="' + thumb + '"' : '';
  Β  Β  Β  Β  Β  Β  Β  Β  Β  attr += value !== '' ? ' data-option-tooltip-value="' + value + '"' : '';
  Β  Β  Β  Β  Β  Β  Β  Β  Β  swatchImageWidth = _.has(sizeConfig, 'swatchImage') ? sizeConfig.swatchImage.width : 30;
  Β  Β  Β  Β  Β  Β  Β  Β  Β  swatchImageHeight = _.has(sizeConfig, 'swatchImage') ? sizeConfig.swatchImage.height : 20;

Β  Β  Β  Β  Β  Β  Β  Β  Β  Β  if (!this.hasOwnProperty('products') || this.products.length <= 0) {
  Β  Β  Β  Β  Β  Β  Β  Β  Β  Β  Β  attr += ' data-option-empty="true"';
  Β  Β  Β  Β  Β  Β  Β  Β  Β  }

Β  Β  Β  Β  Β  Β  Β  Β  Β  Β  if (type === 0) {
  Β  Β  Β  Β  Β  Β  Β  Β  Β  Β  Β  // Text
  Β  Β  Β  Β  Β  Β  Β  Β  Β  Β  Β  var disableCss = '';
  Β  Β  Β  Β  Β  Β  Β  Β  Β  Β  Β  if (!salableId[this.id]) {
  Β  Β  Β  Β  Β  Β  Β  Β  Β  Β  Β  Β  Β  disableCss = 'style="pointer-events:none; background:grey; opacity:0.4;"';
  Β  Β  Β  Β  Β  Β  Β  Β  Β  Β  Β  }

Β  Β  Β  Β  Β  Β  Β  Β  Β  Β  Β  Β  html += '<div ' + disableCss + ' class="' + optionClass + ' text" ' + attr + '>' + (value ? value : label) +
  Β  Β  Β  Β  Β  Β  Β  Β  Β  Β  Β  Β  Β  '</div>';
  Β  Β  Β  Β  Β  Β  Β  Β  Β  } else if (type === 1) {
  Β  Β  Β  Β  Β  Β  Β  Β  Β  Β  Β  // Color
  Β  Β  Β  Β  Β  Β  Β  Β  Β  Β  Β  html += '<div class="' + optionClass + ' color" ' + attr +
  Β  Β  Β  Β  Β  Β  Β  Β  Β  Β  Β  Β  Β  ' style="background: ' + value +
  Β  Β  Β  Β  Β  Β  Β  Β  Β  Β  Β  Β  Β  ' no-repeat center; background-size: initial;">' + '' +
  Β  Β  Β  Β  Β  Β  Β  Β  Β  Β  Β  Β  Β  '</div>';
  Β  Β  Β  Β  Β  Β  Β  Β  Β  } else if (type === 2) {
  Β  Β  Β  Β  Β  Β  Β  Β  Β  Β  Β  // Image
  Β  Β  Β  Β  Β  Β  Β  Β  Β  Β  Β  html += '<div class="' + optionClass + ' image" ' + attr +
  Β  Β  Β  Β  Β  Β  Β  Β  Β  Β  Β  Β  Β  ' style="background: url(' + value + ') no-repeat center; background-size: initial;width:' +
  Β  Β  Β  Β  Β  Β  Β  Β  Β  Β  Β  Β  Β  swatchImageWidth + 'px; height:' + swatchImageHeight + 'px">' + '' +
  Β  Β  Β  Β  Β  Β  Β  Β  Β  Β  Β  Β  Β  '</div>';
  Β  Β  Β  Β  Β  Β  Β  Β  Β  } else if (type === 3) {
  Β  Β  Β  Β  Β  Β  Β  Β  Β  Β  Β  // Clear
  Β  Β  Β  Β  Β  Β  Β  Β  Β  Β  Β  html += '<div class="' + optionClass + '" ' + attr + '></div>';
  Β  Β  Β  Β  Β  Β  Β  Β  Β  } else {
  Β  Β  Β  Β  Β  Β  Β  Β  Β  Β  Β  // Default
  Β  Β  Β  Β  Β  Β  Β  Β  Β  Β  Β  html += '<div class="' + optionClass + '" ' + attr + '>' + label + '</div>';
  Β  Β  Β  Β  Β  Β  Β  Β  Β  }
  Β  Β  Β  Β  Β  Β  Β  });
  Β  Β  Β  Β  Β  Β  Β  return html;
  Β  Β  Β  Β  Β  }
  Β  Β  Β  });

Β  Β  Β  Β  return $.mage.SwatchRenderer;

Β  Β  }

});

Run the below command

php bin/magento se:up && php bin/magento se:s:d -f

You will get the output as below

 

Conclusion:

In this article, we have implemented the functionality of showing out of stock products on the frontend.

Hope this article will help you !!

Thank You.