Adding an image chooser to a Magento 2 widget

Adding image chooser to a widget in Magento 2

In the previous post we have described how to add a new widget in Magento 2. As it was mentioned, each widget field has its own input type. The input type allows determining what graphical interface component will be used to represent this field. Magento 2 has a set of simple input types out of the box such as input field, dropdown etc. Also, it has more complex components: products chooser, rules conditions component, CMS block chooser and others. But in some cases you need to add your own input type, for example if you want to allow choosing an image from media gallery in your widget configuration. In this post we review how to add an image chooser/uploader to your widget.

As a bootstrap we will use the extension we have previously created in the post about adding a widget in Magento 2. For the previously created contact widget we will add an additional field – “photo”. First of all, we need to initialize the new field in the widget.xml file:

…
<parameter name="photo" xsi:type="block" visible="true" sort_order="10">
    <label translate="true">Photo</label>
    <description translate="true">Contact photo</description>

    <block class="Atwix\Widget\Block\Adminhtml\Widget\ImageChooser">
        <data>
            <item name="button" xsi:type="array">
                <item name="open" xsi:type="string">Choose Image...</item>
            </item>
        </data>
    </block>
</parameter>
…

As you can see, the approach for the image chooser field declaration is almost the same as for other widget fields in our module. The only difference is the type of the widget field. We use block type here since we need to add an additional logic to be able to handle the complex graphical component. In the data node we pass some additional arguments, in this case – the button title. Now it’s about time to create the image chooser block:

<?php

namespace Atwix\Widget\Block\Adminhtml\Widget;

use Magento\Framework\Data\Form\Element\AbstractElement as Element;
use Magento\Backend\Block\Template\Context as TemplateContext;
use Magento\Framework\Data\Form\Element\Factory as FormElementFactory;
use Magento\Backend\Block\Template;


class ImageChooser extends Template
{
    /**
     * @var \Magento\Framework\Data\Form\Element\Factory
     */
    protected $elementFactory;

    /**
     * @param TemplateContext $context
     * @param FormElementFactory $elementFactory
     * @param array $data
     */
    public function __construct(
        TemplateContext $context,
        FormElementFactory $elementFactory,
        $data = []
    ) {
        $this->elementFactory = $elementFactory;
        parent::__construct($context, $data);
    }

    /**
     * Prepare chooser element HTML
     *
     * @param Element $element
     * @return Element
     */
    public function prepareElementHtml(Element $element)
    {
        $config = $this->_getData('config');
        $sourceUrl = $this->getUrl('cms/wysiwyg_images/index',
            ['target_element_id' => $element->getId(), 'type' => 'file']);

        /** @var \Magento\Backend\Block\Widget\Button $chooser */
        $chooser = $this->getLayout()->createBlock('Magento\Backend\Block\Widget\Button')
            ->setType('button')
            ->setClass('btn-chooser')
            ->setLabel($config['button']['open'])
            ->setOnClick('MediabrowserUtility.openDialog(\''. $sourceUrl .'\')')
            ->setDisabled($element->getReadonly());

        /** @var \Magento\Framework\Data\Form\Element\Text $input */
        $input = $this->elementFactory->create("text", ['data' => $element->getData()]);
        $input->setId($element->getId());
        $input->setForm($element->getForm());
        $input->setClass("widget-option input-text admin__control-text");
        if ($element->getRequired()) {
            $input->addClass('required-entry');
        }

        $element->setData('after_element_html', $input->getElementHtml() . $chooser->toHtml());

        return $element;
    }
}

In the prepareElementHtml method we create the chooser itself. It’s a simple button created within Magento\Backend\Block\Widget\Button class. For the click event we assign the “MediabrowserUtility.openDialog()” call which opens the standard built-in media chooser window. Now clean the cache and try to add the contact details widget. If you have followed the instruction accurately, you should have the new field with an ability to choose/upload photos. If you have some troubles with adding an image chooser, you can download the entire widget extension on GitHub.

Feel free to leave your ideas and questions in the comments below.

You may also want to read:

Clients

Smart Brands Choose Us.

From startups backed by Mark Cuban and Sir Richard Branson, to some of the biggest eCommerce operations in the world, Atwix helps our clients deliver unparalleled eСommerce experiences. We’re proud to work with the following companies: