|
magento 2 developer

It is true that when it comes to building an eCommerce store, Magento would be the first and only choice due to its ability to be customised in order to meet every requirement the owners may have. Sometimes you may want to play with the variety of colours showing, and for that you need to add a colour picker in the Magento 2 System configuration.

At first it may seem a big task and pretty difficult to achieve, however it is really simple. Below are the exact steps to do this:

  • Step 1: Create Attribute
  • Step 2: Create pickcolors.js, color.html, di.xml files
  • Step 3: Create Pool Modifier Class – Style.php

Note: Replace KiwiCommerce/Attributes from entries in this article to your module name.

Step 1: Create Attribute

Create a product attribute for color with the data given below:

attribute code: my_color

Color picker in form Magento2

Step 2: Create pickcolors.js, color.html, di.xml files

First of all, create pickcolors.js in your module at the path given below and add the following code:

app/code/KiwiCommerce/Attributes/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: 'KiwiCommerce_Attributes/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;
        }
    });
});

Create color.html in your module at the path given below and add the following code:
app/code/KiwiCommerce/Attributes/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>

Create di.xml in your module at the path given below and add the following code:

app/code/KiwiCommerce/Attributes/etc/adminhtml/di.xml

<?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">
       <arguments>
           <argument name="modifiers" xsi:type="array">
               <item name="styles" xsi:type="array">
                   <item name="class" xsi:type="string">KiwiCommerce\Attributes\Ui\Modifier\Product\Style</item>
                   <item name="sortOrder" xsi:type="number">25</item>
               </item>
           </argument>
       </arguments>
   </virtualType>
</config>

Step 3: Create Pool Modifier Class – Style.php

Now, create the class Pool Modifier in your module at the path given below and add the following code:

app/code/KiwiCommerce/Attributes/Ui/Modifier/Product/Style.php

<?php
namespace KiwiCommerce\Attributes\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';
       // Change component js
       $meta['product-details']['children']['container_' . $code]['children'] = array_replace_recursive(
           $meta['product-details']['children']['container_' . $code]['children'], [
           $code => [
               'arguments' => [
                   'data' => [
                       'config' => [
                           'component' => 'KiwiCommerce_Attributes/js/form/element/pickcolors'
                       ]
                   ]
               ]
           ]
       ]);
       return $meta;
   }

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

Woohoo, now clear the cache and the result will be displayed as shown in the image below:
Product edit page:

Magento2 color picker in form

If colour is one of the required attributes then you will see an error message while saving the configuration:

Color picker attribute magento2

That’s it and you can even customize and use this code to place a colour picker anywhere in Magento. Feel free to reach out to us if you find any issues or errors while implementing this code. Wonderful, colourful Magento! ?

3 Comments

  1. Unfortunately, it doesn’t work. pickcolors.js code is totally missing and color.html template isn’t linked anywhere in the code.

    1. Hello Jambalaya, thanks very much for taking the time to tell us.

      We have added the missing js code and you will find a mention of the color.html template in the added pickcolors.js code. Now, it will work for sure, let us know if you have any more issues.

      Thanks again.

  2. Hi,

    This code works fine but the value is not getting saved in the database. Always throws ‘color is not valid’ error, If I remove the validation no value is saved in db in Magento 2.2.9. Please suggest.

Leave a Reply

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