How to enable AJAX for the the 'Add to Cart' button of product widgets in Magento 2?
You have to override addtocart.phtml file
app/design/frontend/vendorname/themename/Magento_Catalog/templates/product/view/addtocart.phtml
Now Just Replace "bindSubmit": false to "bindSubmit": true
<script type="text/x-magento-init">
{
"#product_addtocart_form": {
"catalogAddToCart": {
"bindSubmit": false
}
}
}
</script>
To
<script type="text/x-magento-init">
{
"#product_addtocart_form": {
"catalogAddToCart": {
"bindSubmit": true
}
}
}
</script>
Now delete cache and page_cache folder or flush cache.
Note: Make sure you have to set No from Store->Configuration->Sales->Checkout->Shopping Cart->After Adding a Product Redirect to Shopping Cart to No
You can extend the Catalog Products List
to use the ajax cart by creating a module with the following files:
/Your/Module/Block/Product/ListBlock.php with content:
<?php
namespace Your\Module\Block\Product;
use Magento\CatalogWidget\Block\Product\ProductsList;
class ListBlock extends ProductsList
{
/**
* @var \Magento\Framework\Url\Helper\Data
*/
protected $urlHelper;
public function __construct(
\Magento\Catalog\Block\Product\Context $context,
\Magento\Catalog\Model\ResourceModel\Product\CollectionFactory $productCollectionFactory,
\Magento\Catalog\Model\Product\Visibility $catalogProductVisibility,
\Magento\Framework\App\Http\Context $httpContext,
\Magento\Rule\Model\Condition\Sql\Builder $sqlBuilder,
\Magento\CatalogWidget\Model\Rule $rule,
\Magento\Widget\Helper\Conditions $conditionsHelper,
\Magento\Framework\Url\Helper\Data $urlHelper,
array $data
)
{
$this->urlHelper = $urlHelper;
parent::__construct($context, $productCollectionFactory, $catalogProductVisibility, $httpContext, $sqlBuilder, $rule, $conditionsHelper, $data);
}
/**
* Get post parameters
*
* @param \Magento\Catalog\Model\Product $product
* @return string
*/
public function getAddToCartPostParams(\Magento\Catalog\Model\Product $product)
{
$url = $this->getAddToCartUrl($product);
return [
'action' => $url,
'data' => [
'product' => $product->getEntityId(),
\Magento\Framework\App\ActionInterface::PARAM_NAME_URL_ENCODED =>
$this->urlHelper->getEncodedUrl($url),
]
];
}
}
Your/Module/etc/widget.xml with content:
<widgets xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Widget:etc/widget.xsd">
<widget id="ajax_products_list" class="Your\Module\Block\Product\ListBlock" is_email_compatible="true"
placeholder_image="Magento_CatalogWidget::images/products_list.png" ttl="86400">
<label translate="true">Ajax Catalog Products List</label>
<description translate="true">List of Products with Ajax Cart</description>
<parameters>
<parameter name="title" xsi:type="text" required="false" visible="true">
<label translate="true">Title</label>
</parameter>
<parameter name="show_pager" xsi:type="select" visible="true"
source_model="Magento\Config\Model\Config\Source\Yesno">
<label translate="true">Display Page Control</label>
</parameter>
<parameter name="products_per_page" xsi:type="text" required="true" visible="true">
<label translate="true">Number of Products per Page</label>
<depends>
<parameter name="show_pager" value="1" />
</depends>
<value>5</value>
</parameter>
<parameter name="products_count" xsi:type="text" required="true" visible="true">
<label translate="true">Number of Products to Display</label>
<value>10</value>
</parameter>
<parameter name="template" xsi:type="select" required="true" visible="true">
<label translate="true">Template</label>
<options>
<option name="default" value="Your_Module::product/widget/content/grid.phtml" selected="true">
<label translate="true">Products Grid Template</label>
</option>
</options>
</parameter>
<parameter name="cache_lifetime" xsi:type="text" visible="true">
<label translate="true">Cache Lifetime (Seconds)</label>
<description translate="true">86400 by default, if not set. To refresh instantly, clear the Blocks HTML Output cache.</description>
</parameter>
<parameter name="condition" xsi:type="conditions" visible="true" required="true" sort_order="10"
class="Magento\CatalogWidget\Block\Product\Widget\Conditions">
<label translate="true">Conditions</label>
</parameter>
</parameters>
<containers>
<container name="content">
<template name="grid" value="default" />
</container>
<container name="content.top">
<template name="grid" value="default" />
</container>
<container name="content.bottom">
<template name="grid" value="default" />
</container>
</containers>
</widget>
</widgets>
And finally Your/Module/view/frontend/templates/product/widget/content/grid.phtml with content:
<?php
// @codingStandardsIgnoreFile
use Magento\Framework\App\Action\Action;
?>
<?php
/**
* Template for displaying products list widget
*
* @var $block \Your\Module\Block\Product\ListBlock
*/
?>
<?php if ($exist = ($block->getProductCollection() && $block->getProductCollection()->getSize())):?>
<?php
$type = 'widget-product-grid';
$mode = 'grid';
$image = 'new_products_content_widget_grid';
$title = $block->getTitle() ? __($block->getTitle()) : '';
$products = $block->getProductCollection()->getItems();
$_helper = $this->helper('Magento\Catalog\Helper\Output');
$showWishlist = true;
$showCompare = true;
$showCart = true;
$templateType = \Magento\Catalog\Block\Product\ReviewRendererInterface::DEFAULT_VIEW;
$showDescription = false;
?>
<div class="block widget block-products-list <?php /* @escapeNotVerified */ echo $mode; ?>">
<?php if ($title):?>
<div class="block-title">
<strong><?php /* @escapeNotVerified */ echo $title; ?></strong>
</div>
<?php endif ?>
<div class="block-content">
<?php /* @escapeNotVerified */ echo '<!-- ' . $image . '-->' ?>
<div class="products-<?php /* @escapeNotVerified */ echo $mode; ?> <?php /* @escapeNotVerified */ echo $mode; ?>">
<ol class="product-items <?php /* @escapeNotVerified */ echo $type; ?>">
<?php $iterator = 1; ?>
<?php /** @var \Magento\Catalog\Model\Product $_product */ ?>
<?php foreach ($products as $_product): ?>
<?php /* @escapeNotVerified */ echo($iterator++ == 1) ? '<li class="product-item">' : '</li><li class="product-item">' ?>
<div class="product-item-info" data-container="product-grid">
<?php
$productImage = $block->getImage($_product, $image);
?>
<?php // Product Image ?>
<a href="<?php /* @escapeNotVerified */ echo $_product->getProductUrl() ?>" class="product photo product-item-photo" tabindex="-1">
<?php echo $productImage->toHtml(); ?>
</a>
<div class="product details product-item-details">
<?php
$_productNameStripped = $block->stripTags($_product->getName(), null, true);
?>
<strong class="product name product-item-name">
<a class="product-item-link"
href="<?php /* @escapeNotVerified */ echo $_product->getProductUrl() ?>">
<?php /* @escapeNotVerified */ echo $_helper->productAttribute($_product, $_product->getName(), 'name'); ?>
</a>
</strong>
<?php echo $block->getReviewsSummaryHtml($_product, $templateType); ?>
<?php /* @escapeNotVerified */ echo $block->getProductPrice($_product) ?>
<?php echo $block->getProductDetailsHtml($_product); ?>
<div class="product-item-inner">
<div class="product actions product-item-actions">
<div class="actions-primary">
<?php if ($_product->isSaleable()): ?>
<?php $postParams = $block->getAddToCartPostParams($_product); ?>
<form data-role="tocart-form" action="<?php /* @escapeNotVerified */ echo $postParams['action']; ?>" method="post">
<input type="hidden" name="product" value="<?php /* @escapeNotVerified */ echo $postParams['data']['product']; ?>">
<input type="hidden" name="<?php /* @escapeNotVerified */ echo Action::PARAM_NAME_URL_ENCODED; ?>" value="<?php /* @escapeNotVerified */ echo $postParams['data'][Action::PARAM_NAME_URL_ENCODED]; ?>">
<?php echo $block->getBlockHtml('formkey')?>
<button type="submit"
title="<?php echo $block->escapeHtml(__('Add to Cart')); ?>"
class="action tocart primary">
<span><?php /* @escapeNotVerified */ echo __('Add to Cart') ?></span>
</button>
</form>
<?php else: ?>
<?php if ($_product->getIsSalable()): ?>
<div class="stock available"><span><?php /* @escapeNotVerified */ echo __('In stock') ?></span></div>
<?php else: ?>
<div class="stock unavailable"><span><?php /* @escapeNotVerified */ echo __('Out of stock') ?></span></div>
<?php endif; ?>
<?php endif; ?>
</div>
<div data-role="add-to-links" class="actions-secondary">
<?php if ($this->helper('Magento\Wishlist\Helper\Data')->isAllow()): ?>
<a href="#"
class="action towishlist"
title="<?php echo $block->escapeHtml(__('Add to Wish List')); ?>"
aria-label="<?php echo $block->escapeHtml(__('Add to Wish List')); ?>"
data-post='<?php /* @escapeNotVerified */ echo $block->getAddToWishlistParams($_product); ?>'
data-action="add-to-wishlist"
role="button">
<span><?php /* @escapeNotVerified */ echo __('Add to Wish List') ?></span>
</a>
<?php endif; ?>
<?php
$compareHelper = $this->helper('Magento\Catalog\Helper\Product\Compare');
?>
<a href="#"
class="action tocompare"
title="<?php echo $block->escapeHtml(__('Add to Compare')); ?>"
aria-label="<?php echo $block->escapeHtml(__('Add to Compare')); ?>"
data-post='<?php /* @escapeNotVerified */ echo $compareHelper->getPostDataParams($_product); ?>'
role="button">
<span><?php /* @escapeNotVerified */ echo __('Add to Compare') ?></span>
</a>
</div>
</div>
<?php if ($showDescription):?>
<div class="product description product-item-description">
<?php /* @escapeNotVerified */ echo $_helper->productAttribute($_product, $_product->getShortDescription(), 'short_description') ?>
<a href="<?php /* @escapeNotVerified */ echo $_product->getProductUrl() ?>" title="<?php /* @escapeNotVerified */ echo $_productNameStripped ?>"
class="action more"><?php /* @escapeNotVerified */ echo __('Learn More') ?></a>
</div>
<?php endif; ?>
</div>
</div>
</div>
<?php echo($iterator == count($products)+1) ? '</li>' : '' ?>
<?php endforeach ?>
</ol>
</div>
<?php echo $block->getPagerHtml() ?>
</div>
</div>
<?php if (!$block->isRedirectToCartEnabled()) : ?>
<script type="text/x-magento-init">
{
"[data-role=tocart-form], .form.map.checkout": {
"catalogAddToCart": {}
}
}
</script>
<?php endif; ?>
<?php endif;?>
Be sure and replace all instances of 'Your\Module' with your own namespaces.
Solution for Magento 2.3
For widget Catalog Product list:
You should find template of widget in this case it is
module-catalog-widget/view/frontend/templates/product/widget/content/grid.phtml
and insert this code:
<script type="text/x-magento-init">
{
"[data-role=tocart-form], .form.map.checkout": {
"catalogAddToCart": {}
}
}
</script>