3

Hi I want to add a custom field in Product add/Edit form using UiComponent and want to save its value and displayed back to form as well

I have read a couple of threads for this - but not getting the exact solution

I have added custom field using uicomponent in product_form.xml file below is the code :

<?xml version="1.0" encoding="UTF-8"?>

<form xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Ui:etc/ui_configuration.xsd">   
<modal name="advanced_inventory_modal">  
     <fieldset name="manage_note">
         <argument name="data" xsi:type="array">        
             <item name="config" xsi:type="array">
                 <item name="label" xsi:type="string" translate="true">Manage Note</item>
                 <item name="dataScope" xsi:type="string"/>
                 <item name="sortOrder" xsi:type="number">0</item>
                 <item name="collapsible" xsi:type="boolean">true</item>
                 <item name="opened" xsi:type="boolean">true</item>
             </item>
         </argument>
         <field name="note">
             <argument name="data" xsi:type="array">
                 <item name="config" xsi:type="array">
                     <item name="label" xsi:type="string" translate="true">Notes</item>
                     <item name="formElement" xsi:type="string">textarea</item>
                     <item name="dataScope" xsi:type="string">quantity_and_stock_status.note</item>
                     <item name="sortOrder" xsi:type="number">1</item>
                     <item name="scopeLabel" xsi:type="string">[GLOBAL]</item>
                 </item>
             </argument>
         </field>          
     </fieldset>
     <fieldset name="stock_data">
         <argument name="data" xsi:type="array">
             <item name="config" xsi:type="array">
                 <item name="label" xsi:type="string" translate="true">Stock Configuration</item>
                 <item name="dataScope" xsi:type="string"/>
                 <item name="sortOrder" xsi:type="number">100</item>
                 <item name="collapsible" xsi:type="boolean">true</item>
             </item>
         </argument>
     </fieldset>   
</modal>
</form>

Custom Field is added successfully, but its value is not getting saved ? due to that its value is not displayed in edit form as well.

so what is the best approach to achieve this?

1 Answer 1

6

I have resolved this issue by myself, below is the way i have resolved it.

I have created Observer which calls after product save event.

so below is the events.xml file below is the code :

<?xml version="1.0"?>

<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Event/etc/events.xsd">
    <event name="catalog_product_save_after">
        <observer name="Vendor_Module::save_custom_data" instance="Vendor\Module\Observer\AfterProductSave"/>
    </event>
</config>

Below is my Observer AfterProductSave code :

<?php

namespace Vendor\ModuleName\Observer;

use Magento\Framework\Event\ObserverInterface;

class AfterProductSave implements ObserverInterface
{

    /**
     * Custom factory
     *
     * @var \Vendor\ModuleName\Model\CustomProductsFactory
     */
    protected $_CustomProductsFactory;

    /**
     * Http Request
     *
     * @var \Magento\Framework\App\Request\Http
     */
    protected $request;
    
    
    /**
     * @param \Magento\Customer\Model\ResourceModel\Group\Collection $customerGroup
     * @param \Magento\Framework\App\Request\Http $request
     * @param array $data
     */
    public function __construct(
        \Vendor\ModuleName\Model\CustomProductsFactory $customProductsFactory,
        \Magento\Framework\App\Request\Http $request,
        array $data = []
    ) {
        $this->_CustomProductsFactory = $CustomProductsFactory;
        $this->request = $request;
    }
    
    
    /**
     *
     *  @param \Magento\Framework\Event\Observer $observer
     */
    public function execute(\Magento\Framework\Event\Observer $observer)
    {
        $product = $observer->getProduct();
        
        if ((!empty($product)))) {
            $productId = $product->getId();
            $requestId = $this->request->getParam('id');
            $productName =  $product->getName();
            $customFieldSetData = serialize($product->getCustomFieldSet());
            if ($productId) {
                $this->saveCustomProductData($requestId,$productId,$customFieldSetData);
            }
        }
    }
    

    public function saveCustomProductData($requestId,$productId,$customFieldSetData)
    {
        
        $model = $this->_CustomProductsFactory->create();
        
        if (empty($requestId)) {
            $data = ['custom_data'=>$customFieldSetData,'product_id'=>$productId];
        } else {
            //load model
            $model->load($productId, 'product_id');
            $data = ['custom_data'=>$customFieldSetData,'product_id'=>$productId]];
        }
        
        $model->addData($data);
        
        $model->save();
    }
}

Updated Date:- 10th Aug, 2021

if you can't show value of custom field at Edit Page then try below code

Create di.xml file at Vendor/ModuleName/etc/adminhtml/di.xml

<?xml version="1.0" encoding="UTF-8"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
    <virtualType name="Magento\Catalog\Ui\DataProvider\Product\Form\Modifier\Pool">
        <arguments>
            <argument name="modifiers" xsi:type="array">
                <item name="customTab" xsi:type="array">
                    <item name="class" xsi:type="string">
                        Vendor\ModuleName\Ui\DataProvider\Product\Form\Modifier\CustomField
                    </item>
                    <!-- <item name="sortOrder" xsi:type="number">70</item> -->
                </item>
            </argument>
        </arguments>
    </virtualType>
</config>

then create CustomField.php file at Vendor\ModuleName\Ui\DataProvider\Product\Form\Modifier;

<?php
namespace Vendor\ModuleName\Ui\DataProvider\Product\Form\Modifier;
use Magento\Catalog\Model\Locator\LocatorInterface;
use Magento\Catalog\Ui\DataProvider\Product\Form\Modifier\AbstractModifier;
use Magento\Ui\Component\Form\Fieldset;
use Magento\Ui\Component\Form\Field;
use Magento\Ui\Component\Form\Element\Select;
use Magento\Ui\Component\Form\Element\DataType\Text;
use Magento\Ui\Component\Form\Element\Input;

class CustomField extends AbstractModifier
{
    private $locator;
    
    public function __construct(
        LocatorInterface $locator
    ) {
        $this->locator = $locator;
    }

    public function modifyData(array $data)
    {
        $product   = $this->locator->getProduct();
        $productId = $product->getId();
        $custom_test = $product->getCustom_test(); //this is my custom field

        $data = array_replace_recursive(
            $data, [
                $productId => [
                    'product' => [
                        'custom_test' => $custom_test,
                    ]
                ]
            ]
        ); 
        //Note:- Array Depends on your datascrope string value which one you defined at product_form.xml UI component file...
       //in my case, I defined <item name="dataScope" xsi:type="string">data.product</item> like this in UI component .xml file that's why I use that array format, you have to change according to your case
        return $data;
    }

    public function modifyMeta(array $meta)
    {
        return $meta;
    }
}

In above Modifier File CustomField.php there are two functions,

1st one modifyData() - adding data when the product edit page is loaded.

2nd one modifyMeta() – creating field, fieldset. it is used for create custom field. but it's not necessary to use modifyMeta() for create Custom field, Fieldset in form, If you are using Magento 2 Or above Version then you can add/create field, fieldset using .xml file UI Component

4
  • 1
    do i need to create a 'custom_data' field in the database or it will save automatically? actually i want to add new field for custom images admin can upload multiple images from the product edit page. Aug 3, 2018 at 6:54
  • Please update full code along with creating custom field, i need to create one custom field with name actual_qty, how can i do that? Nov 8, 2018 at 6:46
  • I need to create one custom field with name actual_qty and same like you save and retrieve value during edit, how can i do that? please provide me full code, thanks Nov 8, 2018 at 7:02
  • how to move that custom field into product detail section? Nov 8, 2018 at 8:55

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.