0

I create a custom product attribute with a custom group like this:

     $eavSetup->addAttribute(
        \Magento\Catalog\Model\Product::ENTITY,
        'trademark',
        [
            'type' => 'varchar',
            'label' => 'Trademark',
            'input' => 'text',
            'source' => '',
            'frontend' => '',
            'required' => false,
            'backend' => '',
            'sort_order' => '75',
            'global' => ScopedAttributeInterface::SCOPE_STORE,
            'default' => 'No Trademark',
            'visible' => true,
            'user_defined' => true,
            'searchable' => false,
            'filterable' => false,
            'comparable' => false,
            'visible_on_front' => false,
            'unique' => false,
            'group' => 'General',
            'used_in_product_listing' => false,
            'is_used_in_grid' => true,
            'is_visible_in_grid' => false,
            'is_filterable_in_grid' => false,
            'option' => array('values' => array("")),
            'group' => 'Meridian'
        ]
    );

I apply a custom group fieldset named Meridian to this custom attribute product. I tried to add a custom htmlContent UI component to this custom group, by extending product_form.xml in a custom extension like this:

<?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">
     <fieldset name="Meridian"> 
        <htmlContent name="meridian_extended">
            <block name="space-input" class="Vendor\Module\Block\Adminhtml\Product\Edit\MeridianLocator">
                <arguments>
                    <argument name="template" xsi:type="string">Vendor_Module::catalog/product/edit/meridian-locator.phtml</argument>
                </arguments>
            </block>
        </htmlContent> 
    </fieldset>
</form>

I tried to put the Group name in the fieldset, but when i open the edit product page, the page always becomes blank, when i remove the fieldset the page is there and the html content appears, but it appears at the bottom of the page. I want this htmlContent inside the custom product attribute group, how can i achieve this ?

1 Answer 1

1

If you want to modify product edit form you need to follow another one logic

1. Define custom Product Form modifier

app/code/Acme/StackExchange/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="acme_product_meridian_locator" xsi:type="array">
                    <item name="class" xsi:type="string">Acme\StackExchange\Ui\DataProvider\Product\Form\Modifier\MeridianLocator</item>
                    <item name="sortOrder" xsi:type="number">50</item>
                </item>
            </argument>
        </arguments>
    </virtualType>
</config>

2. Create modifier and modify metadata/data

app/code/Acme/StackExchange/Ui/DataProvider/Product/Form/Modifier/MeridianLocator.php

<?php
declare(strict_types=1);

namespace Acme\StackExchange\Ui\DataProvider\Product\Form\Modifier;

use Magento\Catalog\Model\Locator\LocatorInterface;
use Magento\Catalog\Ui\DataProvider\Product\Form\Modifier\AbstractModifier;
use Symfony\Component\PropertyAccess\PropertyAccess;
use Symfony\Component\PropertyAccess\PropertyAccessorInterface;

class MeridianLocator extends AbstractModifier
{
    public const ATTRIBUTE = 'trademark';

    protected LocatorInterface          $locator;
    protected PropertyAccessorInterface $propertyAccessor;

    public function __construct(
        LocatorInterface $locator,
        ?PropertyAccessorInterface $propertyAccessor = null
    ) {
        $this->locator          = $locator;
        $this->propertyAccessor = $propertyAccessor
            ?: PropertyAccess::createPropertyAccessor();
    }

    /**
     * @inheritDoc
     */
    public function modifyData(array $data)
    {
        // example of update product form data if needed
        $product = $this->locator->getProduct();
        if ($product->getId()) {
            $data[$product->getId()]['product'][self::ATTRIBUTE] = '';
        }
    }

    /**
     * @inheritDoc
     */
    public function modifyMeta(array $meta)
    {
        $group = null;
        foreach ($meta as $groupCode => $groupData) {
            if (!isset($groupData['children']) || !is_array($groupData['children'])) {
                continue;
            }
            foreach ($groupData['children'] as $fieldCode => $fieldData) {
                if ($fieldCode === 'container_' . self::ATTRIBUTE) {
                    $group = $groupCode;
                    break 2;
                }
            }
        }

        if (!$group) {
            return $meta;
        }

        // example to update attribute config
        try {
            $configPath = '[' . $group . '][children][container_notes][children]['.self::ATTRIBUTE.'][arguments][data][config]';
            $config     = $this->propertyAccessor->getValue($meta, $configPath);
            // update config
            $config['template'] = '...';
            $this->propertyAccessor->setValue($meta, $configPath, $config);
        } catch (\Exception $e) {}

        return $meta;
    }
}

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.