I have added a custom tab in admin Products Edit section
http://i.prntscr.com/b78b12c41b3546ba8bd9d657dabcef98.png
The values in the select field are values from my custom tables. I have saved corresponding id of the label and product id to my custom table. I have used the following method for this.
Created a file app/code/Vendor/Module/etc/adminhtml/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">
<virtualType name="Magento\Catalog\Ui\DataProvider\Product\Form\Modifier\Pool">
<arguments>
<argument name="modifiers" xsi:type="array">
<item name="custom-fieldset" xsi:type="array">
<item name="class" xsi:type="string">Vendor\Module\Ui\DataProvider\Product\Form\Modifier\CustomFieldset</item>
<item name="sortOrder" xsi:type="number">10</item>
</item>
</argument>
</arguments>
</virtualType>
</config>
created file app/code/Vendor/Module/Ui/DataProvider/Product/Form/Modifier/CustomFieldset.php
<?php
namespace Vendor\Module\Ui\DataProvider\Product\Form\Modifier;
use Magento\Catalog\Model\Locator\LocatorInterface;
use Magento\Catalog\Ui\DataProvider\Product\Form\Modifier\AbstractModifier;
use Magento\Framework\Stdlib\ArrayManager;
use Magento\Framework\UrlInterface;
use Magento\Ui\Component\Container;
use Magento\Ui\Component\Form\Fieldset;
use Magento\Ui\Component\Form\Element\DataType\Number;
use Magento\Ui\Component\Form\Element\DataType\Text;
use Magento\Ui\Component\Form\Element\Input;
use Magento\Ui\Component\Form\Element\Select;
use Magento\Ui\Component\Form\Element\MultiSelect;
use Magento\Ui\Component\Form\Field;
class CustomFieldset extends AbstractModifier
{
// Components indexes
const CUSTOM_FIELDSET_INDEX = 'custom_fieldset';
const CUSTOM_FIELDSET_CONTENT = 'custom_fieldset_content';
const CONTAINER_HEADER_NAME = 'custom_fieldset_content_header';
// Fields names
const FIELD_NAME_TEXT = 'example_text_field';
const FIELD_NAME_SELECT = 'example_select_field';
const FIELD_NAME_MULTISELECT = 'example_multiselect_field';
/**
* @var \Magento\Catalog\Model\Locator\LocatorInterface
*/
protected $locator;
/**
* @var ArrayManager
*/
protected $arrayManager;
/**
* @var UrlInterface
*/
protected $urlBuilder;
/**
* @var array
*/
protected $meta = [];
protected $productlabelModel;
/**
* @param LocatorInterface $locator
* @param ArrayManager $arrayManager
* @param UrlInterface $urlBuilder
*/
public function __construct(
LocatorInterface $locator,
ArrayManager $arrayManager,
\Vendor\Module\Model\ResourceModel\Productlabel\CollectionFactory $productlabelModel,
UrlInterface $urlBuilder
) {
$this->locator = $locator;
$this->arrayManager = $arrayManager;
$this->productlabelModel = $productlabelModel;
$this->urlBuilder = $urlBuilder;
}
/**
* Data modifier, does nothing in our example.
*
* @param array $data
* @return array
*/
public function modifyData(array $data)
{
return $data;
}
/**
* Meta-data modifier: adds ours fieldset
*
* @param array $meta
* @return array
*/
public function modifyMeta(array $meta)
{
$this->meta = $meta;
$this->addCustomFieldset();
return $this->meta;
}
/**
* Merge existing meta-data with our meta-data (do not overwrite it!)
*
* @return void
*/
protected function addCustomFieldset()
{
$this->meta = array_merge_recursive(
$this->meta,
[
static::CUSTOM_FIELDSET_INDEX => $this->getFieldsetConfig(),
]
);
}
/**
* Declare ours fieldset config
*
* @return array
*/
protected function getFieldsetConfig()
{
return [
'arguments' => [
'data' => [
'config' => [
'label' => __('Product Label'),
'componentType' => Fieldset::NAME,
'dataScope' => static::DATA_SCOPE_PRODUCT, // save data in the product data
'provider' => static::DATA_SCOPE_PRODUCT . '_data_source',
'ns' => static::FORM_NAME,
'collapsible' => true,
'sortOrder' => 10,
'opened' => true,
],
],
],
'children' => [
static::CONTAINER_HEADER_NAME => $this->getHeaderContainerConfig(10),
static::FIELD_NAME_SELECT => $this->getSelectFieldConfig(30),
],
];
}
/**
* Get config for header container
*
* @param int $sortOrder
* @return array
*/
protected function getHeaderContainerConfig($sortOrder)
{
return [
'arguments' => [
'data' => [
'config' => [
'label' => null,
'formElement' => Container::NAME,
'componentType' => Container::NAME,
'template' => 'ui/form/components/complex',
'sortOrder' => $sortOrder,
],
],
],
'children' => [],
];
}
/**
* Example select field config
*
* @param $sortOrder
* @return array
*/
protected function getSelectFieldConfig($sortOrder)
{
return [
'arguments' => [
'data' => [
'config' => [
'label' => __('Product Labels'),
'componentType' => Field::NAME,
'formElement' => Select::NAME,
'dataScope' => static::FIELD_NAME_SELECT,
'dataType' => Text::NAME,
'sortOrder' => $sortOrder,
'options' => $this->_getOptions(),
'visible' => true,
'disabled' => false,
],
],
],
];
}
/**
* Get example options as an option array:
* [
* label => string,
* value => option_id
* ]
*
* @return array
*/
protected function _getOptions()
{
$collection = $this->productlabelModel->create();
$collection->getSelect();
$optionsArray = array();
$optionsArray['none'] = 'None';
foreach($collection as $col){
$optionsArray[$col->getId()] = $col->getProductTitle();
}
$options = [];
foreach ($optionsArray as $key => $value)
{
$options[] = [
'value' => $key,
'label' => $value
];
}
return $options;
}
}
To save declared app/code/Vendor/Module/etc/adminhtml/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">
<event name="catalog_product_save_after">
<observer name="product_label" instance="Vendor\Module\Observer\CatalogProductSavelabelAfterObserver" />
</event>
</config>
Created the observer’s class in app/code/Vendor/Module/Observer/CatalogProductSavelabelAfterObserver.php:
<?php
namespace Vendor\Module\Observer;
use \Magento\Framework\Event\ObserverInterface;
use \Magento\Framework\Event\Observer as EventObserver;
use Vendor\Module\Ui\DataProvider\Product\Form\Modifier\CustomFieldset;
class CatalogProductSavelabelAfterObserver implements ObserverInterface
{
protected $productgridModel;
public function __construct(
\Vendor\Module\Model\Productgrid $productgridModel
) {
$this->productgridModel = $productgridModel;
}
/**
* @param EventObserver $observer
*/
public function execute(\Magento\Framework\Event\Observer $observer)
{
/** @var \Magento\Catalog\Model\Product $product */
$product = $observer->getEvent()->getProduct();
if (!$product) {
return;
}
$productId = $observer->getProduct()->getId();
$id = $product->getData(CustomFieldset::FIELD_NAME_SELECT);
if($id == 'none'){
$productCollection = $this->productgridModel->load($productId,'product_id');
$productCollection->delete();
}
$this->productgridModel->setData('label_id',$id);
$this->productgridModel->setData('product_id',$productId);
$this->productgridModel->save();
$this->productgridModel->unsetData();
}
}
But on editing the same product,the values are not displayed as selected. Hence it is pointing to the first value in the drop down ie,'None'. Please help .