0

I'm a newbie in the Magento! I created the new checkout step "Additional Products" with 2 buttons - "next/skip" and "add to cart". I want to add required products to the cart, but I don't know what I need to write in the addToCart method in my knockout.js file.

This is my template file /var/www/Magento/app/code/Vendor/Module/view/frontend/web/template/additional_products.html:

<li id="additional_products" data-bind="fadeVisible: isVisible" class="additional_products">

<div class="step-title" data-bind="i18n: 'Additional Products'" data-role="title"></div>

<div id="checkout-step-title"
     class="step-content"
     data-role="content">
    <br/>
    <form data-bind="submit: addToCart" novalidate="novalidate" class="form">
        <div class="additional_products" data-bind="foreach: getProductsList()">
            <p>
                <input type="checkbox" name="product_id" data-bind="attr: {id: 'product_id_' +id, value: id}"/>
                <label class="product-detail"
                       data-bind="text: name + ' ' + price, attr: {for: 'product_id_' +id}"></label>
                <img style=" width:100px; height:100px" class="addit_product_img"
                     data-bind="attr: {src: '/pub/media/catalog/product' + thumbnail }">
            </p>
        </div>
        <div class=" actions-toolbar">
            <div class="primary">
                <button data-role="opc-continue" type="submit" class="button action add-to-cart primary">
                    <span data-bind="i18n: 'Add to Cart'"></span>
                </button>
                <button data-role="opc-continue" type="button" class="button action continue primary"
                        data-bind="click: navigateToNextStep">
                    <span data-bind="i18n: 'Skip & Next'"></span>
                </button>
            </div>
        </div>
    </form>
</div>

And this is my knockou.js file /var/www/Magento/app/code/Vendor/Module/view/frontend/web/js/view/additional_products.js

 define(
[
    'ko',
    'uiComponent',
    'underscore',
    'Magento_Checkout/js/model/step-navigator',
    'mage/translate',
    'mage/storage',
    'Magento_Checkout/js/model/full-screen-loader',
    'mage/url',
    'jquery'
],
function (
    ko,
    Component,
    _,
    stepNavigator,
    $t,
    storage,
    fullScreenLoader,
    url,
    $
) {
    'use strict';

    return Component.extend({
        defaults: {
            template: 'Vendor_Module/additional_products.html'
        },

        isVisible: ko.observable(true),

        /**
         *
         * @returns {*}
         */
        initialize: function () {
            this._super();
            // register the new step named "Additional Products"
            stepNavigator.registerStep(
                'additional_products',
                null,
                $t('Additional Products'),
                this.isVisible,
                _.bind(this.navigate, this),
                1
            );

            return this;
        },

        /**
         * The navigate() method is responsible for navigation between checkout step
         * during checkout. You can add custom logic, for example some conditions
         * for switching to your custom step
         */
        navigate: function () {

        },

        /**
         * @returns void
         */
        navigateToNextStep: function () {
            stepNavigator.next();
        },

        /**
         * @returns void
         */
        addToCart: function (formElement) {
            console.log($(formElement).serializeArray());

        },

        /**
         * @returns array
         */
        getProductsList: function () {
            return window.checkoutConfig.additional_products;
        }
    });
}

);enter image description here

How I can add the required product to cart and redirect to the next step?

Thank @SwAt.Be for your message, but I have a problem with the router for this controller. I created the routes.xml file in the Vendor/Module/etc:

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

and controller in the Vendor/Module/Controller/DeleteItems.php with your example for testing ajax call and then I was planning change it.

and I call ajax to the next url

 var actionUrl = url.build('additional-products/Controller/DeleteItem');
  • the url build is wrong. Lets say the id in your routes.xml is additional-products and your controller class is located in Vendor/Module/Controller/DeleteItem then your url build is additional-products/DeleteItem (it already know its looking in the Controller path). Furthermore i suggest putting it in another directory so you have additional-products/NewMap/DeleteItem (just so you do not mix up with other modules) – CompactCode Oct 21 '18 at 14:46
0

You will have to create an ajax call to a controller where you add a product using the checkout Add class.

I do the same thing but reversed to delete an item

define(
    [
        'ko',
        'jquery',
        'uiComponent',
        'underscore',
        'Magento_Checkout/js/model/step-navigator',
        'Magento_Checkout/js/model/quote',
        'Magento_Customer/js/customer-data',
        'mage/url',
        'Magento_Checkout/js/action/get-totals',
    ],
    function (ko,
              $,
              Component,
              _,
              stepNavigator,
              quote,
              customerdata,
              url,
              getTotalsAction) {
        'use strict';
        return Component.extend({
            defaults: {
                template: 'Designit_HideProductByShipping/check-product',
            },

            //add here your logic to display step,
            isVisible: ko.observable(false),
            stepCode: 'check-product',
            stepTitle: 'Product Check',
            ProductItems: ko.observableArray(quote.getItems()),
            minicartSelector: '[data-block="minicart"]',
            /**
             *
             * @returns {*}
             */
            initialize: function () {
....
;
                    }
                });

                return this;
            },

            ajaxDeleteItem: function (item_id, parent) {
                var actionUrl = url.build('routeid/controllerpath/class');
                var item = this;
                $.ajax({
                    url: actionUrl,
                    data: {"item_id": item_id},
                    dataType: 'json',
                    method: 'post',
                    beforeSend: function () {
                        $(parent.minicartSelector).trigger('contentLoading');
                        $(parent.minicartSelector).find('.loading-mask').show();
                    }
                }).done(function (res) {
                    $(parent.minicartSelector).trigger('contentUpdated');
                    $(parent.minicartSelector).find('.loading-mask').hide();
                    if (res.success) {
                        var sections = ['cart'];
                        customerdata.reload(sections, true);
                        parent.ProductItems.remove(item);
                        var deferred = $.Deferred();
                        getTotalsAction([], deferred);
                    }
                });
            },
    }
);

Note that this is an example js with code that has been deleted. It is ment to give you an impression

My Delete controller goes as follow

<?php

namespace Designit\HideProductByShipping\Controller\Checkout;

use Magento\Framework\App\Action\Action;
use Magento\Framework\App\Action\Context;
use Magento\Checkout\Model\Cart;
use Magento\Checkout\Model\Session;
use Magento\Framework\Controller\Result\JsonFactory;
use Magento\Framework\Serialize\Serializer\Json;


class DeleteItem extends Action
{
    /**
     * @var CustomerCart
     */
    protected $cart;
    /**
     * @var Session
     */
    protected $checkoutSession;
    /**
     * @var JsonFactory
     */
    protected $jsonFactory;
    /**
     * @var Json
     */
    protected $jsonHelper;

    /**
     * DeleteItem constructor.
     * @param Context $context
     * @param Session $checkoutSession
     * @param Cart $cart
     * @param JsonFactory $jsonFactory
     * @param Json $jsonHelper
     */
    public function __construct(
        Context $context,
        Session $checkoutSession,
        Cart $cart,
        JsonFactory $jsonFactory,
        Json $jsonHelper
    )
    {
        parent::__construct($context);
        $this->cart = $cart;
        $this->checkoutSession = $checkoutSession;
        $this->jsonFactory = $jsonFactory;
        $this->jsonHelper = $jsonHelper;
    }

    /**
     * Execute action based on request and return result
     *
     * Note: Request will be added as operation argument in future
     *
     * @return \Magento\Framework\Controller\ResultInterface|ResponseInterface
     * @throws \Magento\Framework\Exception\NotFoundException
     */
    public function execute()
    {
        $resultJson = $this->jsonFactory->create();
        $item_id = $this->_request->getParam('item_id');
        try {
            $this->cart->removeItem($item_id)->save();
            $this->checkoutSession->getQuote()->collectTotals()->save();
        } catch (\Exception $e) {
            $this->messageManager->addErrorMessage(__('A problem has occured.'));
            return false;
        }

        $this->messageManager->addSuccessMessage(__('Item has been successfully removed'));

        return $resultJson->setJsonData($this->jsonHelper->serialize(['success' => true]));
    }

This also reloads the totals normally in your checkout.

Upvote and accept if it works for you thanks

  • Thank! I want to make sure your solution works and гpvote it, but I get an error related to the route. I updated the question, could you please help me? – Magento_newbie Oct 20 '18 at 13:15
  • answered you under your update – CompactCode Oct 21 '18 at 14:47
  • Thank you so much, it was very important for me and really helped. I set controller file to Vendor_Module_Controller_Additional_AddToCart.php and ajax call to var actionUrl = url.build('additional/additional/addtocart'); It work, thanks. Then I will look for how to add the necessary products to the cart of the current user. Good luck! – Magento_newbie Oct 22 '18 at 8:51
  • Glad i could help – CompactCode Oct 22 '18 at 11:08

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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