Adding custom product attribute properties in Magento 2

Magento 2 has a lot of configuration options for product attributes. You get things like scope, input validation, use in layered navigation etc. etc. But sometimes thats not enough.
In this tutorial I will show you how to add extra properties to all EAV attributes.

I assume you have some Magento development expierence and I will not describe every step into details, to make it an easier read.

Magento 2.2: I am using Magento version 2.2 as I write this and did not test this on any other version(s).

The property

Tooltip example
A tooltip. Image from UX Planet

Lets say we have a few attributes which need a little extra text when showing them to the customers on the frontend, a little tooltip.

For the simplicity of this tutorial we are using a simple text input without the WYSIWYG editor.

Adding the column to the eav_entity table

To get started set-up a basic Magento 2 module with an UpgradeSchema file.

In our UpgradeSchema.php we want to add a column to the eav_entity table.

We want to use TYPE_TEXT for the type and make it nullable.   The code should look like this:

<?php

namespace Spaggel\Tooltip\Setup;

class UpgradeSchema implements \Magento\Framework\Setup\UpgradeSchemaInterface
{
    public function upgrade(\Magento\Framework\Setup\SchemaSetupInterface $setup, \Magento\Framework\Setup\ModuleContextInterface $context)
    {
        $setup->startSetup();

        if (version_compare($context->getVersion(), '1.1.0', '<=')) {

            $setup->getConnection()->addColumn(
                $setup->getTable('eav_attribute'),
                'tooltip',
                [
                    'type' => \Magento\Framework\DB\Ddl\Table::TYPE_TEXT,
                    'length' => 255,
                    'nullable' => true,
                    'comment' => 'A simple tooltip'
                ]
            );
        }

        $setup->endSetup();
    }
}

Now run the setup upgrade command:

php bin/magento setup:upgrade

We now have the extra column to store our tooltip text (last item in the list).

To actually use the new property we need to override the core attribute form.

 

 

 

 

Extending the product attribute form

Update 01-07-2018: You should use the following event instead of extending the core tab: 

product_attribute_form_build_main_tab

I will update this post asap. Thanks xBitsSec.

The core product attribute form is located in the following namespace:

 Magento\Catalog\Block\Adminhtml\Product\Attribute\Edit\Tab

Because we want our property to be visible on the main tab, we open up $namespace\Tab\Main.php. In this file you find 2 methods, one method called _prepareForm is the one we need. This method calls the abstract parent class called AbstractMain which adds all the fields to the fieldset.

Now we need to find a way to add our field to the form. This can be done in 2 ways:

  1. Edit the main.php file in the vendor folder (warning: this should never be done in production).
  2. Override and extend the file and add our own field.

Creating a form class

We need to create a class somewhere in our module and let it extend the main product attribute tab. Steps to take:

  1. Create a new class called Main.php in the Block namespace of our module.
  2. Let our own Main class extend the following class and alias it to CoreMain:
    Magento\Catalog\Block\Adminhtml\Product\Attribute\Edit\Tab\Main
  3. Create the method _prepareForm with the same signature as the parent class.
  4. Get the fieldset (base_fieldset) and add our own field

The code

My code looks like this:

<?php
namespace Spaggel\Tooltip\Block\Adminhtml\Product\Attribute\Edit\Tab;

use Magento\Catalog\Block\Adminhtml\Product\Attribute\Edit\Tab\Main as CoreMain;

class Main extends CoreMain
{
    protected function _prepareForm()
    {
        parent::_prepareForm();
        $form = $this->getForm();
        $fieldset = $form->getElement('base_fieldset');
        $fieldset->addField(
            'tooltip',
            'text',
            [
                'name'     => 'tooltip',
                'label'    => __('Tooltip'),
                'title'    => __('Tooltip'),
            ]
        );

        return $this;
    }
}

Prefering our own class using di.xml

We’re almost done now. All we need to do is tell Magento to use our own block (form) instead of the default core form. We can achieve this using the di.xml file. Using di.xml we can set a preference for a specific block type and let Magento do the rest.

In our module create the file (in the etc folder): di.xml with the following content:

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
    <preference for="Magento\Catalog\Block\Adminhtml\Product\Attribute\Edit\Tab\Main" type="Spaggel\Tooltip\Block\Adminhtml\Product\Attribute\Edit\Tab\Main" />
</config>

All we need to do now is run the command:

php bin/magento setup:di:compile

to let Magento generate the correct class mapping which will load our own class.

Result

After you ran the di:compile command you can refresh the product attribute edit form and see our new field called Tooltip.

You don’t need to extend the save/update logic because Magento will handle this for you.

Magento 2 attribute tooltip

2 thoughts on “Adding custom product attribute properties in Magento 2”

  1. It is more pretty to use the event ‘product_attribute_form_build_main_tab’ in your owne module 🙂

    No class overriding required an can not break by other module or upgrade 🙂

    Tested in Magento 2.2.5

Leave a Reply

Your email address will not be published. Required fields are marked *