Como adicionar o botão "Empty Cart" ao minicart

10

Como você pode adicionar um botão "Carrinho Vazio" ao minicart no Magento 2.

insira a descrição da imagem aqui

É possível com o layout xml?

Azevinho
fonte

Respostas:

15

Acabei de criar um módulo adequado para sua pergunta:

Precisamos declarar o componente js personalizado e o modelo html:

app / code / Vendor / MiniCart / view / frontend / layout / default.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>
        <referenceBlock name="minicart">
            <arguments>
                <argument name="jsLayout" xsi:type="array">
                    <item name="types" xsi:type="array"/>
                    <item name="components" xsi:type="array">
                        <item name="minicart_content" xsi:type="array">
                            <item name="component" xsi:type="string">Vendor_MiniCart/js/view/minicart</item>
                            <item name="config" xsi:type="array">
                                <item name="template" xsi:type="string">Vendor_MiniCart/minicart/content</item>
                            </item>
                        </item>
                    </item>
                </argument>
            </arguments>
        </referenceBlock>
    </body>
</page>

app / code / Vendor / MiniCart / view / frontend / web / js / view / minicart.js

   define([
    'jquery',
    'Magento_Checkout/js/view/minicart',
    'Magento_Ui/js/modal/alert',
    'Magento_Ui/js/modal/confirm'
], function ($ ,Component, alert, confirm) {
    'use strict';

    return Component.extend({
        confirmMessage: $.mage.__('Are you sure you would like to remove all items from the shopping cart?'),
        emptyCartUrl: window.checkout.emptyMiniCart,

        emptyCartAction: function (element) {
            var self = this,
                href = self.emptyCartUrl;
            $(element).on('click', function () {
                var el = this;
                confirm({
                    content: self.confirmMessage,
                    actions: {
                        confirm: function () {
                            self._removeAllItems(href, el);
                        },
                        always: function (event) {
                            event.stopImmediatePropagation();
                        }
                    }
                });
            });
        },

        _removeAllItems: function (href, elem) {
            $.ajax({
                url: href,
                type: 'post',
                dataType: 'json',
                beforeSend: function () {
                    $(elem).attr('disabled', 'disabled');
                },
                complete: function () {
                    $(elem).attr('disabled', null);
                }

            }).done(function (response) {
                if (!response.errors) {

                } else {
                    var msg = response.message;

                    if (msg) {
                        alert({
                            content: msg
                        });
                    }
                }
            }).fail(function (error) {
                console.log(JSON.stringify(error));
            });
        }
    });
});

emptyCartUrl: window.checkout.emptyMiniCart,obteremos o link vazio em checkout config: app/code/Vendor/MiniCart/Plugin/Cart/ConfigPlugin.php(declarar mais tarde).

Precisamos copiar o conteúdo minicart do arquivo original: vendor/magento/module-checkout/view/frontend/web/template/minicart/content.html. E então, em nosso arquivo personalizado, precisamos adicionar o texto da ação:

app / code / Vendor / MiniCart / view / frontend / web / template / minicart / content.html

 <!-- ko if: getCartParam('summary_count') -->
    <div class="actions">
        <div class="secondary">
            <a class="action empty-cart" id="empty-minicart" data-bind="afterRender: emptyCartAction">
                <span><!-- ko i18n: 'Empty Cart Now' --><!-- /ko --></span>
            </a>
        </div>
    </div>
 <!-- /ko -->

Declare o DI para adicionar o link vazio à configuração da verificação geral:

app / code / Vendor / MiniCart / etc / frontend / di.xml

<?xml version="1.0"?>

<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
    <type name="Magento\Checkout\Block\Cart\Sidebar">
        <plugin name="empty_cart_url" type="Vendor\MiniCart\Plugin\Cart\ConfigPlugin" sortOrder="20" />
    </type>
</config>

app / code / Vendor / MiniCart / Plugin / Cart / ConfigPlugin.php

<?php

namespace Vendor\MiniCart\Plugin\Cart;

use Magento\Framework\UrlInterface;

class ConfigPlugin
{
    /**
     * @var UrlInterface
     */
    protected $url;

    /**
     * ConfigPlugin constructor.
     * @param UrlInterface $url
     */
    public function __construct(
        UrlInterface $url
    ) {
        $this->url = $url;
    }

    /**
     * @param \Magento\Checkout\Block\Cart\Sidebar $subject
     * @param array $result
     * @return array
     */
    public function afterGetConfig(
        \Magento\Checkout\Block\Cart\Sidebar $subject,
        array $result
    ) {
        $result['emptyMiniCart'] = $this->url->getUrl('minicart/cart/emptycart');
        return $result;
    }
}

Agora, precisamos construir o controlador:

app / code / Vendor / MiniCart / etc / frontend / routes.xml

<?xml version="1.0"?>

<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:noNamespaceSchemaLocation="urn:magento:framework:App/etc/routes.xsd">
    <router id="standard">
        <route id="minicart" frontName="minicart">
            <module name="Vendor_MiniCart" />
        </route>
    </router>
</config>

app / code / Vendor / MiniCart / Controller / Cart / EmptyCart.php

<?php

namespace Vendor\MiniCart\Controller\Cart;

use Magento\Framework\Controller\Result\JsonFactory;
use Magento\Framework\Json\Helper\Data;
use Magento\Framework\App\Action\Action;
use Magento\Framework\App\Action\Context;
use Magento\Checkout\Model\Session;
use Psr\Log\LoggerInterface;

class EmptyCart extends Action
{
    /**
     * @var Session
     */
    protected $checkoutSession;

    /**
     * @var JsonFactory
     */
    protected $jsonFactory;

    /**
     * @var Data
     */
    protected $jsonHelper;

    /**
     * @var LoggerInterface
     */
    protected $logger;

    /**
     * @var Magento\Checkout\Model\Cart
     */
    protected $cart;

    /**
     * EmptyCart constructor.
     *
     * @param Context $context
     * @param Session $session
     * @param JsonFactory $jsonFactory
     * @param Data $jsonHelper
     * @param LoggerInterface $logger
     */
    public function __construct(
        Context $context,
        Session $session,
        JsonFactory $jsonFactory,
        Data $jsonHelper,
        LoggerInterface $logger,
        \Magento\Checkout\Model\Cart $cart
    ) {
        $this->checkoutSession = $session;
        $this->jsonFactory = $jsonFactory;
        $this->jsonHelper = $jsonHelper;
        $this->logger = $logger;
        $this->cart = $cart;
        parent::__construct($context);
    }

    /**
     * Ajax execute
     *
     */
    public function execute()
    {
        $response = [
            'errors' => false
        ];

        if ($this->getRequest()->isAjax()) {
            try {
                $this->cart->truncate()->save();
                $response['message'] = __('Empty Cart.');

            } catch (\Exception $e) {
                $response = [
                    'errors' => true,
                    'message' => __('Some thing went wrong.')
                ];
                $this->logger->critical($e);
            }
        } else {
            $response = [
                'errors' => true,
                'message' => __('Need to access via Ajax.')
            ];
        }
        /** @var \Magento\Framework\Controller\Result\Raw $resultRaw */
        $resultJson = $this->jsonFactory->create();
        return $resultJson->setData($response);
    }
}

Precisa recarregar a seção do carrinho:

app / code / Vendor / MiniCart / etc / frontend / seções.xml

<?xml version="1.0"?>

<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Customer:etc/sections.xsd">
    <action name="minicart/cart/empty">
        <section name="cart"/>
    </action>
</config>

Lembre-se de criar registration.phpemodule.xml

app / code / Vendor / MiniCart / registration.php

<?php

\Magento\Framework\Component\ComponentRegistrar::register(
    \Magento\Framework\Component\ComponentRegistrar::MODULE,
    'Vendor_MiniCart',
    __DIR__
);

app / code / Vendor / MiniCart / etc / module.xml

<?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="Vendor_MiniCart" setup_version="1.0.0"/>
</config>

[DEMO DE IMAGENS]

Mini carrinho:

insira a descrição da imagem aqui

Confirmação de mensagem:

insira a descrição da imagem aqui

Khoa TruongDinh
fonte
Obrigado por essa solução detalhada e completa! Funcionou, exceto o código no carrinho vazio. Para fazê-lo funcionar no 2.1.10, tive que alterá-lo um pouco pastebin.com/sYmhqYRL
Viperet
2
E ainda um pouco mais curto pastebin.com/2tMEMdeA
Viperet
11
@Viperet Eu concordo com você. Deve usar $this->cart->truncate()->save();. Sinta-se livre para editar minha resposta.
Khoa TruongDinh
Mini carrinho do @KhoaTruongDinh mostrando apenas o botão "Empty Cart Now" após a implementação do código acima. Qualquer solução?
Vishal
11
Minha versão do Magento é 2.2.6. Você pode por favor me ajudar?
Rohan Hapani