Question

I want to add a new attribute to the product edit form using the UI components, so I created a product_form.xml file in my module, and added the attribute with the code below:

<field name="activate_meta_robots" sortOrder="170" formElement="checkbox">
    <argument name="data" xsi:type="array">
        <item name="config" xsi:type="array">
            <item name="source" xsi:type="string">product</item>
            <item name="default" xsi:type="number">1</item>
        </item>
    </argument>
    <settings>
        <dataType>boolean</dataType>
        <label translate="true">Activate Meta Robots</label>
        <scopeLabel>[STORE VIEW]</scopeLabel>
    </settings>
    <formElements>
        <checkbox>
            <settings>
                <valueMap>
                    <map name="false" xsi:type="number">0</map>
                    <map name="true" xsi:type="number">1</map>
                </valueMap>
                <prefer>toggle</prefer>
            </settings>
        </checkbox>
    </formElements>
</field>

Then, I had to create also the eav attribute in the database in order to save the attribute value. Thus, I created a Data Patch file and added the following code:

$eavSetup->addAttribute(
    Product::ENTITY,
    'activate_meta_robots', [
        'type' => 'int',
        'label' => 'Activate Meta Robots',
        'input' => 'checkbox',
        'source' => Boolean::class,
        'sort_order' => 170,
        'global' => ScopedAttributeInterface::SCOPE_STORE,
        'group' => 'General Information',
    ]
);

But, when I access the Product Edit form, I see the attribute duplicated: one comes from the ui_component:

enter image description here

and the other is the one I add through the addAttribute() method:

enter image description here

I know that I could just remove the ui_component, but I need it. I tried to put 'visible' => false in the addAttribute() method, but in this way the attribute from the ui_component doesn't save its value anymore.

Does anyone know a way to add the attribute created in the ui_component to the db in order to save its value without duplicating the attribute?

Was it helpful?

Solution

I found a solution by myself. I publish here my solution in case anyone else experiences the same issue.

The idea is to hide the attributes rendered through the eav attribute table, to leave only the ones added with the Ui components.

To do that, you need to create a Modifier Pool (https://devdocs.magento.com/guides/v2.4/howdoi/customize-modifier-class.html) and change, at runtime, the formElement attribute of the eav attribute to hidden.

I wrote a small function that you can use to automatically do that:

protected function setupAttributeForUiComponent(array $meta, array $attributeCodes) {
    foreach ($attributeCodes as $attributeCode) {
        // find attribute path
        $path = $this->arrayManager->findPath($attributeCode, $meta, null, 'children');
        // set the attribute as hidden to prevent attribute duplication
        $meta = $this->arrayManager->set("{$path}/arguments/data/config/formElement", $meta, 'hidden');
    }
    return $meta;
}

You can call this method inside the method modifyMeta of your Modifier Pool:

public function modifyMeta(array $meta) {
    $meta = parent::modifyMeta($meta);
    $this->setupAttributeForUiComponent($meta, ["activate_meta_robots"]);
}

Hope it helps.

Licensed under: CC-BY-SA with attribution
Not affiliated with magento.stackexchange
scroll top