0

I want to add an input text field to each product in the cart and save the value in the quote item and sales order tables. Can anyone explain how to do this in Magento 2.4

2
  • Could you please provide additional information about your question? This will help us better understand your situation and provide a more accurate solution.
    – Msquare
    Oct 27, 2023 at 11:06
  • For each product item that is in the cart page I want to add a simple text field underneath the item details that the customer can fill in with a comment. When the order is submitted I want the value of the text field to be stored on the quote item so it can be downloaded by an api later.
    – nickcobb
    Oct 27, 2023 at 14:42

1 Answer 1

0

You have to create Magento 2 custom module. Please follow the below steps

  1. Create registration.php under Vendor/Module folder
<?php
    \Magento\Framework\Component\ComponentRegistrar::register(
        \Magento\Framework\Component\ComponentRegistrar::MODULE,
        'Vendor_Module',
        __DIR__
    ); 
?>

  1. Create module.xml file under the etc folder Vendor/Module/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_Module" setup_version="1.0.1"></module>
</config>
  1. Create events.xml file under the etc folder Vendor/Modue/etc/events.xml
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:noNamespaceSchemaLocation="urn:magento:framework:Event/etc/events.xsd">
   <!-- add option with quote item when add to cart -->
    <event name="checkout_cart_update_items_after">
     <observer name="pf_checkout_cart_items_add_after" instance="Vendor\Module\Observer\CheckoutCartAddObserver" />
    </event>    <!-- add option with quote item with ORDER -->
    <event name="sales_model_service_quote_submit_before">
     <observer name="pf_sales_model_service_quote_submit_before" instance="Vendor\Module\Observer\QuoteSubmitObserver" />
    </event>
</config>
  1. Create Observer for that Vendor/Module/Observer/CheckoutCartAddObserver.php
<?php
    
    
    namespace Vendor\Module\Observer;
    use Magento\Framework\Event\Observer as EventObserver;
    use Magento\Framework\Event\ObserverInterface;/**
     * CheckoutCartAddObserver
     */
    class CheckoutCartAddObserver implements ObserverInterface
    {
        protected $_layout;
        protected $_storeManager;
        protected $_request;
        /**
         * __construct
         *
         * @param \Magento\Store\Model\StoreManagerInterface storeManager
         * @param \Magento\Framework\View\LayoutInterface layout
         * @param \Magento\Framework\App\RequestInterface request
         * @param \Magento\Framework\Serialize\SerializerInterface serializer
         *
         */
        public function __construct(
            \Magento\Store\Model\StoreManagerInterface $storeManager,
            \Magento\Framework\View\LayoutInterface $layout,
            \Magento\Framework\App\RequestInterface $request,
            \Magento\Framework\Serialize\SerializerInterface $serializer
        ) {
            $this->_layout = $layout;
            $this->_storeManager = $storeManager;
            $this->_request = $request;
            $this->serializer = $serializer;
        }
        /**
         * execute
         *
         * @param EventObserver observer
         *
         * @return void
         */
        public function execute(EventObserver $observer)
        {
            $postValue = $this->_request->getParams();
            $cart = $observer->getEvent()->getCart();
            $quote = $cart->getQuote();
            foreach ($quote->getAllVisibleItems() as $item) {
                $productId = $item->getProduct()->getId();
                $qty = $item->getQty();
                 $colorShade = [];
                $colorShade[] = [
                                'label' => 'Custom Text',
                                'value' => $postValue['cart'][$item->getId()]['product_color_shade'],
                        ];
                if (count($colorShade) > 0) {
                    $item->addOption([
                        'product_id' => $item->getProductId(),
                        'code' => 'additional_options',
                        'value' => $this->serializer->serialize($colorShade),
                    ]);
                }
                // You can access other item details as well.
                // Example: $item->getName(), $item->getPrice(), $item->getSku(), etc.
            }
            // Your custom logic here
            return $this;
        }
    }
  1. Create one more Observer Vendor/Module/Observer/QuoteSubmitObserver.php
<?php
    namespace Vendor\Module\Observer;
    use Magento\Framework\Event\Observer as EventObserver;
    use Magento\Framework\Event\ObserverInterface;
    /**
     * QuoteSubmitObserver
     */
    class QuoteSubmitObserver implements ObserverInterface
    {
        private $quoteItems = [];
        private $quote = null;
        private $order = null;
        
        /**
         * __construct
         *
         * @param \Magento\Store\Model\StoreManagerInterface storeManager
         * @param \Magento\Framework\View\LayoutInterface layout
         * @param \Magento\Framework\App\RequestInterface request
         * @param \Magento\Framework\Serialize\SerializerInterface serializer
         *
         */
        public function __construct(
            \Magento\Store\Model\StoreManagerInterface $storeManager,
            \Magento\Framework\View\LayoutInterface $layout,
            \Magento\Framework\App\RequestInterface $request,
            \Magento\Framework\Serialize\SerializerInterface $serializer
        ) {
            $this->_layout = $layout;
            $this->_storeManager = $storeManager;
            $this->_request = $request;
            $this->serializer = $serializer;
        }
        
        /**
         * execute
         *
         * @param EventObserver observer
         *
         * @return void
         */
        public function execute(EventObserver $observer)
        {
            $this->quote = $observer->getQuote();
            $this->order = $observer->getOrder();
            foreach ($this->order->getItems() as $orderItem) {
                if ($quoteItem = $this->getQuoteItemById($orderItem->getQuoteItemId())) {
                    if ($additionalOptionsQuote = $quoteItem->getOptionByCode('additional_options')) {
                        if ($additionalOptionsOrder = $orderItem->getProductOptionByCode('additional_options')) {
                            $additionalOptions = array_merge($additionalOptionsQuote, $additionalOptionsOrder);
                        } else {
                            $additionalOptions = $additionalOptionsQuote;
                        }
                        if (count($additionalOptions->getData()) > 0) {
                            $options = $orderItem->getProductOptions();
                            $options['additional_options'] = $this->serializer->unserialize($additionalOptions->getValue());
                            $orderItem->setProductOptions($options);
                        }
                    }
                }
            }
        }
        /**
         * getQuoteItemById
         *
         * @param mixed id
         *
         * @return void
         */
        private function getQuoteItemById($id)
        {
            if (empty($this->quoteItems)) {
                if ($this->quote->getItems()) {
                    foreach ($this->quote->getItems() as $item) {
                        $this->quoteItems[$item->getId()] = $item;
                    }
                }
            }
            if (array_key_exists($id, $this->quoteItems)) {
                return $this->quoteItems[$id];
            }
            return null;
        }
    }
  1. Now you need to override default.phtml file Located at vendor\magento\module-checkout\view\frontend\templates\cart\item And add additional option after the product name
<input id="cart-<?php echo $_item->getId().'-'.'product_color_shade'; ?>"
          name="cart<?php echo '['.$_item->getId().'][product_color_shade]'; ?>" />

Whenever you update the content in the textbox, click the "Update Cart" button, and the value will be refreshed.

Your Answer

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

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