how can I add the configurable products options in category view page in magento2?

2.7k Views Asked by At

I want to display the configurable product options dropdown in category view page in magento2. Can anyone help me?

Thanks in advance.

3

There are 3 best solutions below

0
On
  • Click On Store In left Menu List
  • Go To attribute section and click on product
  • Search Product Option That you have to show & Click on that attribute
  • Go To Storefront Properties
  • And Change -> in Visible on Catalog Pages on Storefront & Used in Product Listing -> NO to YES and
  • flush your cache or you need to deploy static content.

Cli-> php bin/magento setup:static-contnet:deploy or
php bin/magento setup:static-contnet:deploy -f if you are using magento2.2x.

0
On

Go To

/app/design/frontend/[package]/[theme]/template/catalog/product/list.phtml

Set below-mentioned code within for loop

foreach ($_productCollection as $_product)

<?php if($_product->isConfigurable()): ?>
  //get attributes
  <?php $attributes = $_product->getTypeInstance(true)->getConfigurableAttributes($_product) ?>
  <?php if(count($attributes)): ?>
    <ul>
    <?php foreach($attributes as $att): ?>
      <?php $pAtt=$att->getProductAttribute();
        //get the child products
        $allProducts = $_product->getTypeInstance(true)->getUsedProducts(null, $_product);
        $frontValues =array() ?>
      <li><?php echo $pAtt->getFrontendLabel() ?>
       <ul>
       <?php foreach($allProducts as $p): ?>
         //check stock, status, ...
         //do not show unsaleable options
         <?php if(!$p->isSaleable()) continue; ?>
         <?php $out=$p->getAttributeText($pAtt->getName()); ?>
         <?php $frontValues[$out]=$out; ?>
       <?php endforeach ?>
        <li><?php echo implode('</li><li>', $frontValues) ?></li>
       </ul>
      </li>
    <?php endforeach ?>
    </ul>
  <?php endif ?>
<?php endif ?>

You need to set CSS according to the your website.

1
On

This All depends if your looking to have swatches or dropdowns the answer for dropdowns is not so easy.

First create a custom module. And add the following to your di, file this class stops configurable products getting the correct add to cart.

<type name="Magento\ConfigurableProduct\Model\Product\Type\Configurable">
        <plugin name="remove_possible_by_from_list" type="GremlinTech\CategoryConfigurable\Plugin\Configurable" sortOrder="1"  disabled="false"/>

</type>

Then create a custom php class Under Plugin called configurable

<?php

namespace GremlinTech\CategoryConfigurable\Plugin;

class Configurable
{

    public function afterIsPossibleBuyFromList(\Magento\ConfigurableProduct\Model\Product\Type\Configurable $subject, $result)
    {
        return true;
    }

}

Next step is to overwrite the Magento_Catalog::templates/list.phtml and add the following under the hidden input fields that are already there.

<input type="hidden" name="selected_configurable_option" value="" />
<input type="hidden" name="related_product" id="related-products-field" value="" />
<input type="hidden" name="item"  value="<?= /* @noEscape */ $postParams['data']['product'] ?>" />

Also you need to modify the form element itself to look like below

      <form data-role="tocart-form"
                      id="product_addtocart_form-<?=$_product->getId(); ?>"
                      data-product-sku="<?= $block->escapeHtml($_product->getSku()) ?>"
                      action="<?= $block->getAddToCartUrl($_product) ?>"
                      <?php if ($_product->getOptions()) :?> enctype="multipart/form-data"<?php endif; ?>
                      method="post">

Now your list view has its actual fields, you need to add a catalog_category_view.xml layout either in the theme or in the module created above, and add the following. This will call the product view configurable template into your list.

  <referenceBlock name="category.products.list">
            <block class="Magento\ConfigurableProduct\Block\Product\View\Type\Configurable" name="category.product.configurable" as="configurable_options"  template="Magento_Catalog::product/list/view/type/options/configurable.phtml" />
</referenceBlock>

You will need to do the same for catalogsearch_result_index.xml as the xml is different for search results though uses the same catalog list template

 <referenceBlock name="search_result_list">
            <block class="Magento\ConfigurableProduct\Block\Product\View\Type\Configurable" name="category.product.configurable" as="configurable_options"  template="Magento_Catalog::product/list/view/type/options/configurable.phtml" />
 </referenceBlock>

Now we have this you need to overide the Magento_Catalog::product/list/view/type/options/configurable.phtml template again in the theme or module, you then need to make it look like the below.

<?php
/**
 * Copyright © Magento, Inc. All rights reserved.
 * See COPYING.txt for license details.
 */
?>

<?php
/** @var $block \Magento\ConfigurableProduct\Block\Product\View\Type\Configurable*/
$_product    = $block->getProduct();
if($_product->getTypeId() === 'configurable') :
$_attributes = $block->decorateArray($block->getAllowAttributes());
?>
<?php if ($_product->isSaleable() && count($_attributes)) :?>
    <?php foreach ($_attributes as $_attribute) : ?>
        <div class="field configurable required">
            <label class="label" for="attribute<?= $block->escapeHtmlAttr($_attribute->getAttributeId()) ?>">
                <span><?= $block->escapeHtml($_attribute->getProductAttribute()->getStoreLabel()) ?></span>
            </label>
            <div class="control">
                <select name="super_attribute[<?= $block->escapeHtmlAttr($_attribute->getAttributeId()) ?>]"
                        data-selector="super_attribute[<?= $block->escapeHtmlAttr($_attribute->getAttributeId()) ?>]"
                        data-validate="{required:true}"
                        id="attribute<?= $block->escapeHtmlAttr($_attribute->getAttributeId()) ?>"
                        class="super-attribute-select">
                    <option value=""><?= $block->escapeHtml(__('Choose an Option...')) ?></option>
                </select>
            </div>
        </div>
    <?php endforeach; ?>
    <script type="text/x-magento-init">
        {
            "[data-role=priceBox][data-price-box=product-id-<?= $block->escapeJs($_product->getId()) ?>]": {
                "priceBox": {}
            }
        }
    </script>
    <script type="text/x-magento-init">
        {
            "#product_addtocart_form-<?=$_product->getId(); ?>": {
                "configurable": {
                    "selectSimpleProduct" : ".cart-price.product-<?=$_product->getId(); ?> [name=selected_configurable_option]",
                    "priceHolderSelector" : ".cart-price.product-<?=$_product->getId(); ?> > .price-box",
                    "spConfig": <?= /* @noEscape */ $block->getJsonConfig() ?>,
                    "gallerySwitchStrategy": "<?= $block->escapeJs($block->getVar(
                        'gallery_switch_strategy',
                        'Magento_ConfigurableProduct'
                    ) ?: 'replace'); ?>"
                }
            },
            "*" : {
                "Magento_ConfigurableProduct/js/catalog-add-to-cart": {}
            }
        }
    </script>
<?php endif;?>
<?php endif;?>


What has changed from default configurable.phtml

We added the below init script this makes the prices dynamic on the grid itself, without the below prices fail to inizalize and configurable options with static prices would fail.

 <script type="text/x-magento-init">
        {
            "[data-role=priceBox][data-price-box=product-id-<?= $block->escapeJs($_product->getId()) ?>]": {
                "priceBox": {}
            }
        }
    </script>

We have also modified the paramatersin the configurable x-init to make them more specific to the grid inidviual items otherwise all prices would change on each item and so would the hidden configurable_selected hidden item.

Final Thing to do is to call the options in the loop in your list.phtml again, within the scope of the form,

  <?= $block->getChildBlock("configurable_options")->setData('product', $_product)->toHtml(); ?>

What we are doing is getting our child block and setting the specific list item as the product on the block otherwise it would try and use the registry like it does on product view.

Thats it hope this helps.