In this article we are going to create a simple module that will add a fieldset with fields in the product editing UI-form. Also, we will create an observer to intercept this data during the product saving.

First, we need to create a Vendor_Product module:

1. Create a directory app/code/Vendor/Product
2. Create a registration file app/code/Vendor/Product/registration.php with the following content:

Create a composer file (if you plan to transfer the module) app/code/Vendor/Module/composer.json :

Now, create the module’s main XML-file app/code/Vendor/Product/etc/module.xml with the dependency from the Magento_Catalog module because our modal window will be added to its form:

Enable the module by entering the following: bin/magento module:enable Vendor_Product and bin/magento setup:upgrade in the root Magento directory.

Then, add the content of the module: the UI-form meta-data and virtual type for its addition.

Create a file app/code/Vendor/Product/etc/adminhtml/di.xml. We are going to place a modifier inside:

The modifier is responsible for data addition and some manipulations with elements and UI-form components. There are 2 main methods that came from the modifier’s interface (they should always present):

We are going to use the modifyMeta method in this example. The modifyData method will be explained in the next article.

Now, create the modifier file (app/code/Vendor/Product/Ui/DataProvider/Product/Form/Modifier/CustomFieldset.php) with a custom fieldset for the product editing page and fill it with the fields:

In this example we need to take the existing UI-form meta-data and merge it (not rewrite!) with our new data:

When done, add the new fieldset to the getFieldsetConfig method:

We inherit from the abstract product UI-form modifier and use its namespace and data as a provider: ‘provider’ => static::DATA_SCOPE_PRODUCT . ‘_data_source’ (where DATA_SCOPE_PRODUCT is the ‘data.product’ line).

The componentType option is one of the main options and is responsible for the component type. The collapsible option is responsible for collapsing and expanding of our fieldset. And the open option defines wheter the fieldset will be open by default during the form drawing.

Then, we consequently add a header to our fieldset in the getHeaderContainerConfig method and 3 examples of fields: text, select and multiselect. However, our product and form won’t receive data until we add it to the modifyData method. But we have the ability to transmit and intercept the data during saving.

Let’s see how the form is look:

The data saving takes place inside the product controller file vendor/magento/module-catalog/Controller/Adminhtml/Product/Save.php in the main execute method. If everything has been done in the right way, then our data will be displayed correctly in the input data of this method:

Note, if your product doesn’t have those attributes from the beginning, you should save them manually. You can do this in the observer.

First, declare it in the app/code/Vendor/Product/etc/adminhtml/events.xml file (we are using the adminhtml scope because the form doesn’t exist on the front-end):

Then, create the observer’s class that we pointed in the instance attribute – app/code/Vendor/Product/Observer/ProductSaveAfter.php:

The data in the observer:

Now, you can call your own model from the observer and save data in it or modify it as you wish.

Be careful! If the saving of your model is connected with the product saving, then it can lead to the recurssion.