4

I am trying to remove the options from bundles (in Magento 2), so that Bundle Items can be added straight to the Cart without users being able to customise these options.

I thought the easiest way to do this would be to remove the customise button from the product page and replace it with the Add to cart button which appears in the Customise options. This has worked as far as the visual aspects are concerned. I have added Magento_Bundle/layout/catalog_product_view_type_bundle.xml with the following code which does this:

<?xml version="1.0"?>
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
    <body>  
        <move element="product.info.addtocart.bundle" destination="product.info.main" after="product.info.price"/>
        <referenceBlock name="customize.button" remove="true" />
    </body>
</page>

So far, so good! However, this Add to cart button doesn't work! There seems to be some Javascript which must kick in, in the block below, which I need to add here (or in a different file) perhaps?

Any ideas??

1
  • I read somewhere that the customise block that comes up at the bottom of bundle products (when you click on the "Customize" button), sets the product ID (hidden form field). Is this still the case for Magento 2? If yes, could someone provide a code snippet I could add to the above example (I assume in a separate file) to do this. Alternatively, setup a separate module that kicks in each time a bundle item is viewed and runs this code?
    – noobie77
    Feb 29, 2016 at 1:12

2 Answers 2

7

When I saw this page come up in Google I was cautiously optimistic. Several hours of bashing my keyboard into the wall later, here is what worked for me:

Magento_Bundle/layout/catalog_product_view_type_bundle.xml:

<?xml version="1.0"?>
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
    <body>
        <move element="bundle.options.container" destination="product.info.main" after="product.info.price"/>
        <container name="product.info.social.wrapper" />
        <move element="product.info.social.wrapper" destination="product.info.main" after="bundle.options.container" />
        <move element="product.info.social" destination="product.info.social.wrapper"/>
        <referenceBlock name="customize.button" remove="true" />
    </body>
</page>

And then some (admittedly nasty) css:

.bundle-options-wrapper{
  display: none;
}
.bundle-options-container {
  display: flex;
  margin-bottom: 0px;
}
.bundle-options-container .product-add-form{
  display: block;
}
.block-bundle-summary{
  float: left;
  padding: 0;
  width: inherit;
  background-color: inherit;
}
.block-bundle-summary .title,
.block-bundle-summary .content .bundle-summary,
.block-bundle-summary .content .bundle-info .product-image-container,
.block-bundle-summary .content .bundle-info .product-details strong,
.block-bundle-summary .content .bundle-info .product-details p,
.block-bundle-summary .content .bundle-info .product-details .price-box,
.block-bundle-summary .content .bundle-info .product-details .product-addto-links {
  display: none;
}

And at the end you have the entire customization block at the bottom of the page hidden inside the product info container, allowing the add to cart button to work. This css is what made it look like my regular product pages, you may need to adjust it for your theme.

Hopefully someone will benefit from my struggle.

2
  • Hi @Dominic Ferrantelli , It's possible send Bundle direct to cart on list.phtml ?
    – Matt Silva
    Feb 24, 2017 at 14:27
  • can you explain what you are doing here? i cant apply it on my case. I would like to know the so I can devise a solution for my own
    – Damathryx
    Dec 9, 2018 at 14:56
4

OK as a complete solution to this using @Dominic Ferrantelli initial answer and also the logic required to add the bundle product to the cart straight from the category page as well please see below:

@Dominic Ferrantelli Answer - Start

Magento_Bundle/layout/catalog_product_view_type_bundle.xml

<?xml version="1.0"?>
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
    <body>
        <move element="bundle.options.container" destination="product.info.main" after="product.info.price"/>
        <container name="product.info.social.wrapper" />
        <move element="product.info.social.wrapper" destination="product.info.main" after="bundle.options.container" />
        <move element="product.info.social" destination="product.info.social.wrapper"/>
        <referenceBlock name="customize.button" remove="true" />
    </body>
</page>

@Dominic Ferrantelli Answer - End

@Dominic Ferrantelli answer removes all the unwanted bundle elements from the page but keeping the bundle wrapper which contains the bundle add to cart form.

My Extended answer - Start

instead of using @Dominic Ferrantelli styles you could use this .less instead

app/design/Vendor/ThemeName/web/css/source/_theme.less

.catalog-product-view {
    .block-bundle-summary {
        .title, .product-image-container, .product-details .product.name, .bundle-summary, .price, .available.stock {display:none;}
    }
    .bundle-options-wrapper {display:none;}
}

Now to add the bundle add to cart logic to the category you need to do the following:

Create a custom module (plenty of online documentation for this so I wont cover it here) and add the following:

Declare observer / method rewrite

app\code\Vendor\Module\etc\frontend\di.xml

<?xml version="1.0"?>

<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../lib/internal/Magento/Framework/ObjectManager/etc/config.xsd">
    <preference for="Magento\Catalog\Block\Product\ListProduct" type="Vendor\Module\Block\Frontend\CategoryCartParams" />
</config>

Rewrite the Magento\Catalog\Block\Product\ListProduct::getAddToCartPostParams() method with the following:

app\code\Vendor\Module\Block\Frontend\CategoryCartParams.php

<?php

namespace Vendor\Module\Block\Frontend;

use Magento\Catalog\Api\CategoryRepositoryInterface;
use Magento\Catalog\Model\Category;
use Magento\Catalog\Model\Product;
use Magento\Eav\Model\Entity\Collection\AbstractCollection;
use Magento\Framework\Exception\NoSuchEntityException;
use Magento\Framework\DataObject\IdentityInterface;

class CategoryCartParams extends \Magento\Catalog\Block\Product\ListProduct
{

    /**
     * Default toolbar block name
     *
     * @var string
     */
    protected $_defaultToolbarBlock = 'Magento\Catalog\Block\Product\ProductList\Toolbar';

    /**
     * Product Collection
     *
     * @var AbstractCollection
     */
    protected $_productCollection;

    /**
     * Catalog layer
     *
     * @var \Magento\Catalog\Model\Layer
     */
    protected $_catalogLayer;

    /**
     * @var \Magento\Framework\Data\Helper\PostHelper
     */
    protected $_postDataHelper;

    /**
     * @var \Magento\Framework\Url\Helper\Data
     */
    protected $urlHelper;

    /**
     * @var CategoryRepositoryInterface
     */
    protected $categoryRepository;

    /**
     * @param Context $context
     * @param \Magento\Framework\Data\Helper\PostHelper $postDataHelper
     * @param \Magento\Catalog\Model\Layer\Resolver $layerResolver
     * @param CategoryRepositoryInterface $categoryRepository
     * @param \Magento\Framework\Url\Helper\Data $urlHelper
     * @param array $data
     */
    public function __construct(
        \Magento\Catalog\Block\Product\Context $context,
        \Magento\Framework\Data\Helper\PostHelper $postDataHelper,
        \Magento\Catalog\Model\Layer\Resolver $layerResolver,
        CategoryRepositoryInterface $categoryRepository,
        \Magento\Framework\Url\Helper\Data $urlHelper,
        array $data = []
    ) {
        parent::__construct($context, $postDataHelper, $layerResolver, $categoryRepository, $urlHelper, $data);
    }

    /**
     * Get post parameters
     *
     * @param \Magento\Catalog\Model\Product $product
     * @return string
     */
    public function getAddToCartPostParams(\Magento\Catalog\Model\Product $product)
    {

        if ($product->getTypeId() == \Magento\Bundle\Model\Product\Type::TYPE_CODE)
        {

            $url = $this->getAddToCartUrl($product);

            $selectionCollection = $product->getTypeInstance(true)
                ->getSelectionsCollection(
                    $product->getTypeInstance(true)->getOptionsIds($product),
                    $product
                );

            $bundleOptions = '?';

            foreach($selectionCollection as $selection)
            {

                $bundleOptions .= '&bundle_option[' . $selection->getOptionId() . ']=' . $selection->getSelectionId();
                $bundleOptions .= '&bundle_option_qty[' . $selection->getOptionId() . ']=' . $selection->getSelectionQty();

            }

            $url .= $bundleOptions;

            return [
                'action' => $url,
                'data' => [
                    'product' => $product->getEntityId(),
                    \Magento\Framework\App\ActionInterface::PARAM_NAME_URL_ENCODED => $this->urlHelper->getEncodedUrl($url),
                ]
            ];

        } else
        {

            $url = $this->getAddToCartUrl($product);
            return [
                'action' => $url,
                'data' => [
                    'product' => $product->getEntityId(),
                    \Magento\Framework\App\ActionInterface::PARAM_NAME_URL_ENCODED =>
                        $this->urlHelper->getEncodedUrl($url),
                ]
            ];

        }

    }

}

This rewrite basically adds a query string of all the bundle options for the parent product and appends it to the add to cart url if a bundled product.

This is all tested and working as I needed to build this for my current project.

2
  • As an additional note if you get construct errors within the observer/preference you will need to delete the contents of var/generation.
    – Tony Brown
    Mar 15, 2017 at 14:05
  • this worked on the category page, how do i do this on product page
    – Damathryx
    Dec 9, 2018 at 12:48

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.