Como ativar o AJAX para o botão 'Adicionar ao carrinho' de widgets de produtos no Magento 2?

10

No Magento 2, o Add to Cartbotão normal possui uma lógica muito boa baseada em AJAX para adicionar produtos ao carrinho.
No entanto, quando usamos um Catalog Products Listwidget, por exemplo, nas páginas do CMS, o botão nesta lista de produtos funciona com um HTTP POSTque recarrega a página atual.

A experiência do usuário sofre com isso e seria desejável que o botão tivesse a mesma lógica AJAX como nas listas de produtos da categoria padrão ou nas páginas de produtos.

Como podemos estender o Catalog Products Listwidget para que ele use o botão melhor Add to Cart ? Ou talvez haja outra solução alternativa?

Jey DWork
fonte
Eu acredito que você quis dizer em "páginas CMS", não em "páginas CSS". :)
Iveta Allogenes
@IvetaAllogenes editou ;-) #
11264 Jey DWork 20/02

Respostas:

22

Você precisa substituir o arquivo addtocart.phtml

app/design/frontend/vendorname/themename/Magento_Catalog/templates/product/view/addtocart.phtml

Agora basta substituir "bindSubmit": false para "bindSubmit": true

<script type="text/x-magento-init">
    {
        "#product_addtocart_form": {
            "catalogAddToCart": {
                "bindSubmit": false
            }
        }
    }
</script>

Para

<script type="text/x-magento-init">
    {
        "#product_addtocart_form": {
            "catalogAddToCart": {
                "bindSubmit": true
            }
        }
    }
</script>

Agora exclua o cache e a pasta page_cache ou limpe o cache.

Nota: Certifique-se de definir Não de Store->Configuration->Sales->Checkout->Shopping Cart->After Adding a Product Redirect to Shopping Cart to No

Prince Patel
fonte
Este código não está funcionando no magento 2.2.3.
Ashna
Como podemos adicionar add ajax ao carrinho no grid.html para o widget página inicial em 2.2.3
Ashna
@ Patel Prince, como isso pode ser re-iniciado? Eu instalei rolagem ajax, então adicionar ao carrinho não está funcionando após a resposta
Jafar pinjar
@jafarpinjar Este é o código Magento padrão. Verifique o módulo de rolagem ajax para obter o problema.
Prince Patel
Ele está trabalhando para mim depois da mudança para este arquivo com este "bindSubmit": true
Sarfaraj Sipai
6

Você pode estender o Catalog Products Listpara usar o carrinho ajax criando um módulo com os seguintes arquivos:

/Your/Module/Block/Product/ListBlock.php com conteúdo:

<?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),
            ]
        ];
    }
}

Seu / Module / etc / widget.xml com conteúdo:

<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>

E finalmente, seu / Module / view / frontend / templates / product / widget / content / grid.phtml com o conteúdo:

<?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;?>

Certifique-se de substituir todas as instâncias do 'Your \ Module' pelos seus próprios namespaces.

Aaron Allen
fonte
1
Não tenho certeza do que você alterou no arquivo phtml. Pode coisas que você talvez claras por dizer o que você mudou e por que (os outros filles são bastante simples)
CompactCode
2

No Magento 2.2, o Magento_Catalog/product/view/validationscript é chamado em vez de catalogAddToCart.

Isso já está presente em addtocart.phtml(com a radioCheckboxClosestopção de configuração), portanto, para ativar o Ajax Add to Cart, basta adicionar a bindSubmitopção da seguinte forma:

<script type="text/x-magento-init">
{
    "#product_addtocart_form": {
        "Magento_Catalog/product/view/validation": {
            "bindSubmit": true,
            "radioCheckboxClosest": ".nested"
        }
    }
}
</script>
thaddeusmt
fonte
Adicionando essa configuração não funciona para mim
Joshua Flood
Trabalhou perfeitamente na v2.2.3, obrigado!
Kristjan O.
1

Nos últimos lançamentos do Magento 2, isso foi alterado novamente e agora é

<script type="text/x-magento-init">
    {
        "#product_addtocart_form": {
            "Magento_Catalog/js/validate-product": {
                "bindSubmit": true
            }
        }
    }
</script>
Daniel Ruf
fonte
1

Solução para Magento 2.3

Para a lista de produtos do catálogo de widgets:

Você deve encontrar o modelo do widget, neste caso, é

widget-catálogo-de-módulos / view / frontend / templates / produto / widget / content / grid.phtml

e insira este código:

<script type="text/x-magento-init">
    {
        "[data-role=tocart-form], .form.map.checkout": {
            "catalogAddToCart": {}
        }
    }
</script>
Oleg Usik
fonte
Funciona bem. Obrigado.
Aji