3

How to add below in my custom widget.xml?

enter image description here

below code does not have possibility of multiple products selection :(

<parameter name="id_path" xsi:type="block" visible="true" required="true" sort_order="10">
                <label translate="true">Product</label>
                <block class="Magento\Catalog\Block\Adminhtml\Product\Widget\Chooser">
                    <data>
                        <item name="button" xsi:type="array">
                            <item name="open" xsi:type="string">Select Product...</item>
                        </item>
                    </data>
                </block>
</parameter>
4

The solution ;)

In widget.xml of the custom module:

<parameter name="multi_product_chooser" xsi:type="block" visible="true" required="true" sort_order="10">
      <label translate="true">Select Products</label>
      <block class="MyVendor\MyModule\Block\Chooser" />
</parameter>

and Chooser block like below:

<?php
namespace MyVendor\MyModule\Block;

class Chooser extends \Magento\Backend\Block\Template
{

    protected $_elementFactory;

    /**
     * @param \Magento\Backend\Block\Template\Context $context
     * @param \Magento\Framework\Data\Form\Element\Factory $elementFactory
     * @param array $data
     */
    public function __construct(
        \Magento\Backend\Block\Template\Context $context,
        \Magento\Framework\Data\Form\Element\Factory $elementFactory, array $data = []
    )
    {
        $this->_elementFactory = $elementFactory;
        parent::__construct($context, $data);
    }

    /**
     * Prepare chooser element HTML
     *
     * @param \Magento\Framework\Data\Form\Element\AbstractElement $element Form Element
     * @return \Magento\Framework\Data\Form\Element\AbstractElement
     */
    public function prepareElementHtml(\Magento\Framework\Data\Form\Element\AbstractElement $element)
    {
        $htmlId = $element->getId();
        $data = $element->getData();

        $data['after_element_js'] = $this->_afterElementJs($element);
        $data['after_element_html'] = $this->_afterElementHtml($element);
        $data['readonly'] = 'readonly';
        $htmlItem = $this->_elementFactory->create('text', ['data' => $data]);
        $htmlItem
            ->setId("{$htmlId}")
            ->setForm($element->getForm())
            ->addClass('required-entry')
            ->addClass('entities');
        $return = <<<HTML
                <div id="{$htmlId}-container" class="chooser_container">{$htmlItem->getElementHtml()}</div>
HTML;
        $element->setData('after_element_html', $return);
        return $element;
    }

    protected function _afterElementHtml($element)
    {
        $htmlId = $element->getId();
        $return = <<<HTML
            <a href="javascript:void(0)" onclick="MultiProductChooser.displayChooser('{$htmlId}-container')" class="widget-option-chooser" title="{__('Open Chooser')}">
                <img src="{$this->getViewFileUrl('images/rule_chooser_trigger.gif')}" alt="{__('Open Chooser')}" />
            </a>
            <a href="javascript:void(0)" onclick="MultiProductChooser.hideChooser('{$htmlId}-container')" title="{__('Apply')}">
                <img src="{$this->getViewFileUrl('images/rule_component_apply.gif')}" alt="{__('Apply')}">
            </a>
            <div class="chooser skuchooser"></div>
HTML;
        return $return;
    }

    protected function _afterElementJs($element)
    {
        $chooserUrl = $this->getUrl('adminhtml/widget_instance/products', []);
        $htmlId = $element->getId();
        $return = <<<HTML
            <script>
                    require([
                    'jquery',
                    'Magento_Ui/js/modal/alert',
                    "prototype"
                ], function (jQuery, alert) {
                    var MultiProductChooser = {
                        displayChooser : function(chooser) {
                            chooser  = $(chooser).down('div.chooser');
                            entities = chooser.up('div.chooser_container').down('input[type="text"].entities').value;
                            postParameters = {selected: entities};
                            url = '{$chooserUrl}';
                            if (chooser && url) {
                                if (chooser.innerHTML == '') {
                                        new Ajax.Request(url, {
                                        method  : 'post',
                                        parameters : postParameters,
                                        onSuccess  : function(transport) {
                                            try {
                                                if (transport.responseText) {
                                                    Element.insert(chooser, transport.responseText);
                                                    chooser.removeClassName('no-display');
                                                    chooser.show();
                                                }
                                            } catch (e) {
                                                alert({
                                                   content: 'Error occurs during loading chooser.'
                                                });
                                            }
                                        }
                                    });
                                } else {
                                    chooser.removeClassName('no-display');
                                    chooser.show();
                                }
                            }
                       },
                        hideChooser : function(chooser) {
                                chooser = $(chooser).down('div.chooser');
                                if (chooser) {
                                chooser.addClassName('no-display');
                                chooser.hide();
                                }
                        },
                        addProductItemToSelection: function(groupId, item) {
                            if (!isNaN(parseInt(item))) {
                                this.selectedItems[groupId].set(item, 1);
                            }
                        },
                        checkProduct : function(event) {                            
                            var cont = document.querySelector(".skuchooser");
                            var elm = event.memo.element,
                            container = event.target.up('div.chooser').up('div.chooser_container');
                            var matches = cont.querySelector("tr.on-mouse");
                            var mat = matches.querySelector("td.col-chooser_sku");                          
                            value = container.down('input[type="text"].entities').value.strip();
                            pickedSku = mat.childNodes[0].nodeValue;                 
                            pickedSku = pickedSku.trim();
                            if (elm.checked) {
                                if (value) ids = value.split(',');
                                else ids = [];

                                if (-1 == ids.indexOf(pickedSku)) {
                                    ids.push(pickedSku);
                                    container.down('input[type="text"].entities').value = ids.join(',');
                                }
                            } else {
                                ids = value.split(',');

                                while (-1 != ids.indexOf(pickedSku)) {
                                    ids.splice(ids.indexOf(pickedSku), 1);
                                    container.down('input[type="text"].entities').value = ids.join(',');
                                }
                            }                          
                          }
                      }
                    window.MultiProductChooser = MultiProductChooser;
                    jQuery(function() {
                        var container = $('{$htmlId}-container');
                        if (container) {
                            container.up(0).down('.control-value').hide();
                        }              
                         Event.observe(document, 'product:changed', function(event){
                            MultiProductChooser.checkProduct(event);
                        });
                        Event.observe(document, 'category:beforeLoad', function(event) {
                                container = event.target.up('div.chooser_container');
                                value   = container.down('input[type="text"].entities').value.strip();
                            event.memo.treeLoader.baseParams.selected = value;
                        });
                    });
                });
            </script>
HTML;
        return $return;
    }
}
| improve this answer | |
  • Hello @Zinat, I have list of sku, can we create widget dynamically and load the products in list manner.. – jafar pinjar Jul 15 '19 at 7:44

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.