How can I add a color picker in custom form field in admin magento 2?
Note: not in system-config
Vendor/Module/view/adminhtml/ui_component/your_form.xml
<?xml version="1.0"?>
<form xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Ui:etc/ui_configuration.xsd">
<fieldset name="content">
<field name="my_color_picker">
<argument name="data" xsi:type="array">
<item name="config" xsi:type="array">
<item name="component" xsi:type="string">Vendor_Module/js/form/element/color-select</item>
<item name="template" xsi:type="string">ui/form/field</item>
<item name="elementTmpl" xsi:type="string">Vendor_Module/form/element/color-select</item>
<item name="label" xsi:type="string">My Color Picker</item>
<item name="labelVisible" xsi:type="boolean">true</item>
<item name="visible" xsi:type="boolean">true</item>
<item name="dataType" xsi:type="string">text</item>
<item name="formElement" xsi:type="string">input</item>
<item name="source" xsi:type="string">category_form</item>
</item>
</argument>
</field>
</fieldset>
</form>
It's essentially a generic text input, but we've defined a unique elementTmpl and component.
Vendor/Module/view/adminhtml/web/js/form/element/color-select.js
define([
'Magento_Ui/js/form/element/abstract',
'mageUtils',
'jquery',
'jquery/colorpicker/js/colorpicker'
], function (Element, utils, $) {
'use strict';
return Element.extend({
defaults: {
visible: true,
label: '',
error: '',
uid: utils.uniqueid(),
disabled: false,
links: {
value: '${ $.provider }:${ $.dataScope }'
}
},
initialize: function () {
this._super();
},
initColorPickerCallback: function (element) {
var self = this;
$(element).ColorPicker({
onSubmit: function(hsb, hex, rgb, el) {
self.value(hex);
$(el).ColorPickerHide();
},
onBeforeShow: function () {
$(this).ColorPickerSetColor(this.value);
}
}).bind('keyup', function(){
$(this).ColorPickerSetColor(this.value);
});
}
});
});
I'm initiating the color picker with an afterRender callback. In my use case the element was not rendered on the page when my component was initialized, so adding the color picker in the initial method did not work for me.
Vendor/Module/view/adminhtml/web/template/form/element/color-select.html
<input class="admin__control-text" type="text"
data-bind="
event: {change: userChanges},
value: value,
hasFocus: focused,
valueUpdate: valueUpdate,
afterRender: initColorPickerCallback,
attr: {
name: inputName,
placeholder: placeholder,
'aria-describedby': noticeId,
id: uid,
disabled: disabled
}"/>
You'll also want to add the color picker css as a layout update, so the filename will vary:
Vendor/Module/view/adminhtml/layout/{frontName}{controller}{action}.xml
<?xml version="1.0" encoding="UTF-8"?>
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" layout="admin-2columns-left" xsi:noNamespaceSchemaLocation="../../../../../../../lib/internal/Magento/Framework/View/Layout/etc/page_configuration.xsd">
<head>
<css src="jquery/colorpicker/css/colorpicker.css"/>
</head>
</page>
Change in your code system.xml
Find your field for color picker.
Replace Below Code.
<field id="your_field_id" translate="label" type="text" sortOrder="10" showInDefault="1" showInWebsite="1" showInStore="1">
<label>Background Color</label>
<frontend_model>MyVendor\MyModule\Block\ColorPicker</frontend_model>
</field>
Please Created a new file ColorPicker.php in your MyVendor\MyModule\Block\ColorPicker
Add below code in your ColorPicker.php
<?php
namespace MyVendor\MyModule\Block;
class ColorPicker extends \Magento\Config\Block\System\Config\Form\Field{
/**
* @param \Magento\Backend\Block\Template\Context $context
* @param array $data
*/
public function __construct(
\Magento\Backend\Block\Template\Context $context,
array $data = []
) {
parent::__construct($context, $data);
}
/**
* add color picker in admin configuration fields
* @param \Magento\Framework\Data\Form\Element\AbstractElement $element
* @return string script
*/
protected function _getElementHtml(\Magento\Framework\Data\Form\Element\AbstractElement $element)
{
$html = $element->getElementHtml();
$value = $element->getData('value');
$html .= '<script type="text/javascript">
require(["jquery"], function ($) {
$(document).ready(function (e) {
$("#'.$element->getHtmlId().'").css("background-color","#'.$value.'");
$("#'.$element->getHtmlId().'").colpick({
layout:"hex",
submit:0,
colorScheme:"dark",
color: "#'.$value.'",
onChange:function(hsb,hex,rgb,el,bySetColor) {
$(el).css("background-color","#"+hex);
if(!bySetColor) $(el).val(hex);
}
}).keyup(function(){
$(this).colpickSetColor(this.value);
});
});
});
</script>';
return $html;
}
}
?>