I want to create a custom tab in back-end product edit module of Magento 2.1. Like this
I tried this and tried to know how Magento adds these tabs. But didn't find a solution.
Please help me find the correct solution.
I want to create a custom tab in back-end product edit module of Magento 2.1. Like this
I tried this and tried to know how Magento adds these tabs. But didn't find a solution.
Please help me find the correct solution.
Magento 2.1 :- You can use this code for simple custom tab add in product edit page. Create Own module and put below code in Vendor/Module/view/adminhtml/layout/catalog_product_new.xml
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
<body>
<referenceBlock name="product_form">
<block class="Vendor\Module\Block\Adminhtml\Product\Edit\Tab\Welcome" name="product.welcome" as="custom-tab" >
<arguments>
<argument name="config" xsi:type="array">
<item name="label" xsi:type="string" translate="true">Product Welcome</item>
<item name="collapsible" xsi:type="boolean">true</item>
<item name="opened" xsi:type="boolean">true</item>
<item name="sortOrder" xsi:type="string">2</item>
<item name="canShow" xsi:type="boolean">true</item>
<item name="componentType" xsi:type="string">fieldset</item>
</argument>
</arguments>
</block>
</referenceBlock>
</body>
</page>
In block Vendor/Module/Block/Adminhtml/Product/Edit/Tab/Welcome.php put below code.
<?php
namespace Vendor\Module\Block\Adminhtml\Product\Edit\Tab;
use Magento\Backend\Block\Template\Context;
use Magento\Framework\Registry;
class Welcome extends \Magento\Framework\View\Element\Template
{
protected $_template = 'catalog/product/edit/welcome.phtml';
protected $_coreRegistry = null;
public function __construct(
Context $context,
Registry $registry,
array $data = []
)
{
$this->_coreRegistry = $registry;
parent::__construct($context, $data);
}
public function getProduct()
{
return $this->_coreRegistry->registry('current_product');
}
}
In templates Vendor/Module/view/adminhtml/templates/catalog/product/edit/welcome.phtml put below code.
<div class="welcome">
<?php echo __('Welcome !'); ?>
</div>
Now Check back-end product module of Magento 2.1. It's working perfect.
Create the di.xml
in adminhtml scope:
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="mageworx-option-dependency" xsi:type="array">
<item name="class" xsi:type="string">Vendor\Module\Ui\DataProvider\Product\Form\Modifier\Name</item>
<item name="sortOrder" xsi:type="number">71</item>
</item>
</argument>
</arguments>
</virtualType>
</config>
Then add your Vendor\Module\Ui\DataProvider\Product\Form\Modifier\Name
:
app/code/Vendor/Module/Ui/DataProvider/Product/Form/Modifier/Name.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;
class Name extends AbstractModifier
{
const SAMPLE_FIELDSET_NAME = 'custom_fieldset';
const SAMPLE_FIELD_NAME = 'sample_field';
/**
* @var \Magento\Catalog\Model\Locator\LocatorInterface
*/
protected $locator;
/**
* @var ArrayManager
*/
protected $arrayManager;
/**
* @var UrlInterface
*/
protected $urlBuilder;
/**
* @var array
*/
protected $meta = [];
/**
* @param LocatorInterface $locator
* @param ArrayManager $arrayManager
* @param UrlInterface $urlBuilder
*/
public function __construct(
LocatorInterface $locator,
ArrayManager $arrayManager,
UrlInterface $urlBuilder
) {
$this->locator = $locator;
$this->arrayManager = $arrayManager;
$this->urlBuilder = $urlBuilder;
}
public function modifyData(array $data)
{
return array_replace_recursive(
$data,
[
$this->locator->getProduct()->getId() => [
static::DATA_SOURCE_DEFAULT => [
static::SAMPLE_FIELD_NAME => $this->locator->getProduct()->getData(static::SAMPLE_FIELD_NAME),
]
]
]
);
}
public function modifyMeta(array $meta)
{
$this->meta = $meta;
$this->addFieldset();
return $this->meta;
}
protected function addFieldset()
{
$this->meta = array_replace_recursive(
$this->meta,
[
static::SAMPLE_FIELDSET_NAME => [
'arguments' => [
'data' => [
'config' => [
'label' => __('Sample Fieldset'),
'componentType' => Fieldset::NAME,
'dataScope' => 'data.product',
'collapsible' => true,
'sortOrder' => 10,
],
],
],
'children' => [
'header_container' => $this->getHeaderContainerConfig(10),
// Add children here
],
],
]
);
return $this;
}
/**
* 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,
'sortOrder' => $sortOrder,
'content' => __('Sample content.'),
],
],
],
'children' => [
'sample_container' => $this->getSampleContainer(10),
],
];
}
protected function getSampleContainer($sortOrder)
{
return [
'arguments' => [
'data' => [
'config' => [
'label' => null,
'formElement' => Fieldset::NAME,
'componentType' => Fieldset::NAME,
'sortOrder' => $sortOrder,
'additionalClasses' => 'admin__field-wide',
],
],
],
'children' => [
static::SAMPLE_FIELD_NAME => $this->getSampleFieldConfig(10)
],
];
}
protected function getSampleFieldConfig($sortOrder)
{
return [
'arguments' => [
'data' => [
'config' => [
'label' => __('Sample Field'),
'componentType' => \Magento\Ui\Component\Form\Field::NAME,
'formElement' => \Magento\Ui\Component\Form\Element\Input::NAME,
'dataScope' => static::SAMPLE_FIELD_NAME,
'dataType' => \Magento\Ui\Component\Form\Element\DataType\Text::NAME,
'sortOrder' => $sortOrder,
'validation' => [
'letters-with-basic-punc' => true,
],
'required' => true,
],
],
],
'children' => [],
];
}
}
Your new empty fieldset with example field:
Validation is working:
When saving a product your data will be automatically applied to it:
See: \Magento\Catalog\Controller\Adminhtml\Product\Initialization\Helper::initializeFromData()
. Thus if the product has the respective field, then your value will be saved. Another way you need to use an observer or some kind of plugins (before the product saving process).
You can take more examples from:
vendor/magento/module-catalog/Ui/DataProvider/Product/Form/Modifier
To get the current product you can use the $this->locator->getProduct()
.
Name
field in Dependency.php? and do i need to create a separate name
class?
Dependency.php
should be the Name.php
, it's a typo, sorry). So you need to create app/code/Vendor/Module/Ui/DataProvider/Product/Form/Modifier/Name.php
with a namespace Vendor\Module\Ui\DataProvider\Product\Form\Modifier
and a class name Name
.
Commented
Aug 16, 2016 at 8:56
modifyData
method; adds constants). I can share a full example from the my module, but there a lot of code (more than 1k lines only in modifier).
Commented
Aug 16, 2016 at 9:05