0

I'm trying to add color picker attribute in product form

I have referred this link:- https://kiwicommerce.co.uk/blog/how-to-add-a-color-picker-in-product-edit-form-in-magento-2/?unapproved=1745&moderation-hash=3ee404bde1e2041476b04e80ed232540#comment-1745

But i'm getting Undefined index: container_[attribute_code] in my case my_color. I'm adding attribute using data patch. I'm adding my files below,

Also making changes according this answer https://magento.stackexchange.com/a/323055/73212

Vendor/Module/etc/adminhtml/di.xml

<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="addColorPicker" xsi:type="array">
                    <item name="class" xsi:type="string">Vendor\Module\Ui\Modifier\Product\Style</item>
                    <item name="sortOrder" xsi:type="number">30</item>
                </item>
           </argument>
       </arguments>
   </virtualType>
</config>

Vendor/Module/Ui/Modifier/Product/Style.php

<?php
namespace Vendor\Module\Ui\Modifier\Product;

use Magento\Catalog\Ui\DataProvider\Product\Form\Modifier\AbstractModifier;

class Style extends AbstractModifier
{
   public function modifyMeta(array $meta)
   {
       // Color attribute
        $code = 'my_color';

        $meta['product-details']['children']['container_' . $code]['children'] = array_replace_recursive(
            $meta['product-details']['children']['container_' . $code]['children'], [
            $code => [
                'arguments' => [
                    'data' => [
                        'colorPicker' => [
                            'component' => 'Vendor_Module/js/form/element/pickcolors'
                        ]
                    ]
                ]
            ]
        ]); 
       return $meta;
   }

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

Vendor/Module/view/base/web/template/form/element/color.html

<div class="swatches-visual-col col-default">
    <div class="swatch_window" style="background: #000000"
         data-bind="
         style: {'background-color': value},
         'aria-describedby': noticeId,
         id: uid, disabled: disabled,
         attr: {title: placeholder},
         hasFocus: focused
    "></div>
 </div>

Vendor/Module/view/base/web/js/form/element/pickcolors.js

define([
    'Magento_Ui/js/form/element/abstract',
    'mageUtils',
    'jquery',
    'jquery/colorpicker/js/colorpicker'
], function (Abstract, utils, $) {
    'use strict';
    return Abstract.extend({
        defaults: {
            placeholder: $.mage.__('Select Colors'),
            elementTmpl: 'Vendor_Module/form/element/color',
            links: {
                value: '${ $.provider }:${ $.dataScope }'
            }
        },
        /**
         * Calls 'initObservable' of parent
         *
         * @returns {Object} Chainable.
         */
        initObservable: function () {
            this._super()
                .observe('disabled visible value')
                .observe('addText');

            return this;
        },
        /**
         * Initializes regular properties of instance.
         *
         * @returns {Abstract} Chainable.
         */
        initConfig: function () {
            var uid = utils.uniqueid(),
                valueUpdate;
            this._super();
            valueUpdate = this.showFallbackReset ? 'afterkeydown' : this.valueUpdate;
            _.extend(this, {
                uid: uid,
                noticeId: 'notice-' + uid,
                valueUpdate: valueUpdate
            });
            console.log(this);
            return this;
        },
        /**
         * Initialize ColorPicker
         *
         * @returns {boolean}
         */
        initColorPicker: function() {
            var self = this;
            $('[data-role="color-picker"]').ColorPicker({
                color: self.value(),
                onShow: function (colpkr) {
                    $(colpkr).fadeIn(200);
                    return false;
                },
                onHide: function (colpkr) {
                    $(colpkr).fadeOut(200);
                    return false;
                },
                onChange: function (hsb, hex) {
                    $('#color-121').css('backgroundColor', '#' + hex);
                    self.userChanges();
                    self.value('#' + hex);
                    self.hasChanged();
                }
            });
            return false;
        },
        /**
         * Validates itself by it's validation rules using validator object.
         * If validation of a rule did not pass, writes it's message to
         * 'error' observable property.
         *
         * @returns {Object} Validate information.
         */
        validate: function () {
            var value   = this.value(),
                result  = this.checkColor(value),
                message = !this.disabled() && this.visible() ? result.message : '',
                isValid = this.disabled() || !this.visible() || result.passed;

            this.error(message);
            this.bubble('error', message);

            if (!isValid) {
                this.source.set('params.invalid', true);
            }

            return {
                valid: false,
                target: this
            };
        },
        checkColor: function(value) {
            var result = {message: $.mage.__('Color is not valid'), passed:false};
            if (/(^#[0-9A-F]{6}$)|(^#[0-9A-F]{3}$)/i.test(value)) {
                result = { message: '', passed: true };
            }
            return result;
        }
    });
});

Please let me know if anyone has any idea.

1

1 Answer 1

0

Keep only these files (remove the others from your example, you don't need them):

  • Vendor/Module/etc/adminhtml/di.xml (unchanged)
  • Vendor/Module/Ui/Modifier/Product/Style.php
<?php

namespace Vendor\Module\Ui\Modifier\Product;

use Magento\Catalog\Ui\DataProvider\Product\Form\Modifier\AbstractModifier;
use Magento\Framework\Stdlib\ArrayManager;

class Style extends AbstractModifier
{
    /**
     * @var ArrayManager
     */
    protected ArrayManager $arrayManager;

    /**
     * @param ArrayManager $arrayManager
     */
    public function __construct(ArrayManager $arrayManager)
    {
        $this->arrayManager = $arrayManager;
    }

    public function modifyMeta(array $meta)
    {
        // Color attribute
        $code = 'my_color';
        $elementPath = $this->arrayManager->findPath($code, $meta, null, 'children');
        $containerPath = $this->arrayManager->findPath(
            sprintf("%s%s", static::CONTAINER_PREFIX, $code),
            $meta,
            null,
            'children'
        );
        if (!$elementPath) {
            return $meta;
        }

        $this->arrayManager->merge(
            $containerPath,
            $meta,
            [
                'children' => [
                    $code => [
                        'arguments' => [
                            'data' => [
                                'config' => [
                                    'formElement' => 'colorPicker',
                                    'colorPickerMode' => 'full',
                                    'colorFormat' => 'hex',
                                ],
                            ],
                        ],
                    ],
                ],
            ]
        );
    }

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

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.