I'm facing to a very ridiculous trouble, I added a custom product attribute with source model, backend model as a select box. Everything works fine (my custom attribute will get the values from a custom table) except the input_renderer part.

Here is what I tried, (running on default mode)


public function getDefaultEntities()
    return [
        'catalog_product' => [
            'entity_model' => 'Magento\Catalog\Model\ResourceModel\Product',
            'attribute_model' => 'Magento\Catalog\Model\ResourceModel\Eav\Attribute',
            'table' => 'catalog_product_entity',
            'additional_attribute_table' => 'catalog_eav_attribute',
            'entity_attribute_collection' => 'Magento\Catalog\Model\ResourceModel\Product\Attribute\Collection',
            'attributes' => [
                'custom_ids' => [
                    'type' => 'static',
                    'input' => 'select',
                    'label' => 'Custom Attribute',
                    'global' => ScopedAttributeInterface::SCOPE_GLOBAL,
                    'backend' => 'Vendor\Module\Model\Product\Attribute\Backend\CustomAttr',
                    'source' => 'Vendor\Module\Model\Product\Attribute\Source\CustomAttr',
                    'input_renderer' => 'Vendor\Module\Block\Adminhtml\Product\Helper\Form\CustomAttr',
                    'required' => false,
                    'sort_order' => 9,
                    'visible' => true,
                    'group' => 'General',
                    'is_used_in_grid' => false,
                    'is_visible_in_grid' => false,
                    'is_filterable_in_grid' => false,


class CustomAttr extends \Magento\Framework\Data\Form\Element\Select
    public function getAfterElementHtml()
        if (!$this->isAllowed()) {
            return '';

        $htmlId = $this->getHtmlId();
        $suggestPlaceholder = __('start typing to search custom attribute');
        $selectorOptions = $this->jsonEncoder->encode($this->getSelectorOptions());
        $backendUrl = $this->backendData->getUrl('vendor_module/customattr_index/index/suggestCustomAttr');

            = <<<HTML
   /** Some HTML and JavaScript here **/

        return $return;

I tried to die() inside getAfterElementHtml() method, but nothing happens. I even go to the database and change the value of column frontend_input_renderer in table catalog_eav_attribute to something doesn't exists.

But there is NO ERROR at all !!! Magento 2 just simply to denied to call my input renderer :)

Anyone here have any suggestions or a best pratices for this?

Thank you.

2 Answers 2


TL;DR: If you need to customise your custom attribute in product edit form Magento 2, use PHP modifier in UI components instead of input renderer.

I found the solution myself.

As we all knew that Magento 2 using UI components, the solution I'm talking about here is PHP modifier in UI components.

From Magento 2 devdocs:

PHP modifiers that are the server-side part of UI components configuration. Using modifiers is optional and might be necessary when static declaration in XML configuration files is not suitable for the tasks. For example, in cases when additional data should be loaded from database. Or the other specific example is the default product creation form, for which the modifier is a place where validations are added to display only certain fields for certain product types.

By default, Magento 2 using PHP modifiers to render EAV attribute. They never use input_renderer to do so. If you are reading here, I assume that you need few examples, so here you are :)


namespace Vendor\Module\Ui\DataProvider\Product\Form\Modifier;

use Magento\Catalog\Api\Data\ProductAttributeInterface;
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\Form\Field;

 * Data provider for "Custom Attribute" field of product page
class CustomAttr extends AbstractModifier
    const SUGGEST_FILTER_URI = 'vendor_module/something/suggestCustomAttr';

     * @param LocatorInterface            $locator
     * @param UrlInterface                $urlBuilder
     * @param ArrayManager                $arrayManager
    public function __construct(
        LocatorInterface $locator,
        UrlInterface $urlBuilder,
        ArrayManager $arrayManager
    ) {
        $this->locator = $locator;
        $this->urlBuilder = $urlBuilder;
        $this->arrayManager = $arrayManager;

     * {@inheritdoc}
    public function modifyMeta(array $meta)
        $meta = $this->customiseCustomAttrField($meta);

        return $meta;

     * {@inheritdoc}
    public function modifyData(array $data)
        return $data;

     * Customise Custom Attribute field
     * @param array $meta
     * @return array
    protected function customiseCustomAttrField(array $meta)
        $fieldCode = 'custom_ids'; //your custom attribute code
        $elementPath = $this->arrayManager->findPath($fieldCode, $meta, null, 'children');
        $containerPath = $this->arrayManager->findPath(static::CONTAINER_PREFIX . $fieldCode, $meta, null, 'children');

        if (!$elementPath) {
            return $meta;

        $meta = $this->arrayManager->merge(
                'arguments' => [
                    'data' => [
                        'config' => [
                            'label'         => __('Custom Attribute'),
                            'dataScope'     => '',
                            'breakLine'     => false,
                            'formElement'   => 'container',
                            'componentType' => 'container',
                            'component'     => 'Magento_Ui/js/form/components/group',
                            'scopeLabel'    => __('[GLOBAL]'),
                'children'  => [
                    $fieldCode => [
                        'arguments' => [
                            'data' => [
                                'config' => [
                                    'component'     => 'Vendor_Module/js/components/your-select-js',
                                    'componentType' => Field::NAME,
                                    'formElement'   => 'select',
                                    'elementTmpl'   => 'ui/grid/filters/elements/ui-select',
                                    'disableLabel'  => true,
                                    'multiple'      => false,
                                    'options'       => $this->getOptions(),
                                    'filterUrl'     => $this->urlBuilder->getUrl(
                                        ['isAjax' => 'true']
                                    'config'           => [
                                        'dataScope' => $fieldCode,
                                        'sortOrder' => self::FIELD_ORDER,

        return $meta;

     * Retrieve custom attribute collection
     * @return array
    protected function getOptions()
        // Get your options


<?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">
            <argument name="modifiers" xsi:type="array">
                <item name="custom-attribute" xsi:type="array">
                    <item name="class" xsi:type="string">Vendor\Module\Ui\DataProvider\Product\Form\Modifier\CustomAttr</item>
                    <item name="sortOrder" xsi:type="number">10</item>

Above is example of two important file which ping Magento 2 to render your custom attribute fields in product edit form to whatever you want. You will need to customise with javascript if you want it plays smoothly.

And yes, welcome to Magento 2 most painful's world - UI components.

  • 1
    be sure that sortOrder is more than 150 ;) Commented Oct 18, 2016 at 17:16
  • This works for the product edit form but does not seem to work for the attribute mass update form. From what I can see the attribute form doesn't use UI components yet. I don't know why Magento allowed this kind of inconsistency!
    – micwallace
    Commented Sep 12, 2019 at 9:25
  • Great tips, thanks! I am also trying to so this type of thing without any luck. Do you know how I could only replace a custom product attribute field by a block such as: $this->layoutFactory->create()->createBlock('Vendor\Module\Block\Adminhtml\MyBlock')->toHtml() ?
    – jony974
    Commented Mar 17, 2020 at 13:59

It sounds like you have errors disabled, can you turn developer mode on by using the Magento CLI or you can add this near your code error_reporting(-1);

bin/magento deploy:mode:set developer


  • I tried both but nothing happened. Commented Oct 6, 2016 at 4:20

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.