0

I need to add dynamic rows into the custom-made-widget, without uiComponent. I have a system.xml with the block:

<section id="general" type="text">
   <group id="quantity_ranges" translate="label" type="text" sortOrder="10" showInDefault="1" showInWebsite="1" showInStore="1">
       <label>Quantity Ranges</label>
         <field id="ranges" translate="label" sortOrder="0" showInDefault="1" showInWebsite="1" showInStore="1">
             <label>Ranges</label>
                <frontend_model>Vendor\module\Block\Adminhtml\Form\Field\DynamicRows</frontend_model>
...

and the Block: Vendor\module\Block\Adminhtml\Form\Field\DynamicRows

class DynamicRows extends AbstractFieldArray
{
    public function _prepareToRender()
    {
        $this->addColumn('sku', ['label' => __('Sku'), 'class' => 'required-entry']);
        $this->addColumn('position', ['label' => __('Position'), 'class' => 'required-entry']);

        $this->_addAfter = false;
        $this->_addButtonLabel = __('Add');
    }
} 

and it works. BUT, I need this into the widget, which does NOT work:

<parameter name="hotspots" xsi:type="block" required="false" visible="true">
  <label translate="true">Hotspots products</label>
  <block class="Vendor\Module\Block\Adminhtml\Form\Field\Hospot" />
</parameter>

block: \Vendor\Module\Block\Adminhtml\Form\Field\Hospot

class Hospot extends Template
{
    public function prepareElementHtml(AbstractElement $element): AbstractElement
    {
        // Create the dynamics rows
        $dynamicRows = $this->getLayout()->createBlock(AbstractFieldArray::class);
        $dynamicRows->addColumn('label', ['label' => __('Sku')]);
        $dynamicRows->addColumn('position', ['label' => __('Position')]);

        $element->setData('after_element_html', $dynamicRows->toHtml() . "<script>require(['mage/adminhtml/browser']);</script>");

        return $element;
    }
}

Has anyone had faced this particular case?

1

In your new Vendor\Module\Block\Adminhtml\Form\Field\Hospot class you're trying to create a block from an abstract class. This is not possible. Instead, you should use a separate class that is instantiated from the given abstract class. And additionally, you have to set an $element for this new class. So here is how your Vendor\Module\Block\Adminhtml\Form\Field\Hospot class should look like:

<?php

namespace Vendor\Module\Block\Adminhtml\Form\Field;

use Magento\Framework\Data\Form\Element\AbstractElement;
use Magento\Framework\View\Element\Template;

class Hotspot extends Template
{
    public function prepareElementHtml(AbstractElement $element)
    {
        $dynamicRows = $this->getLayout()
            ->createBlock(
                DynamicRows::class
            )->setElement(
                $element
            );

        $element->setData('after_element_html', $dynamicRows->toHtml() . "<script>require(['mage/adminhtml/browser']);</script>");

        return $element;
    }
}

BUT! When trying to save the widget you will be getting an error. Because in Magento\Widget\Model\Widget::getDirectiveParam() Magento tries to implode the array of the widget settings. And since the dynamic rows value is a multi-level array, it cannot be converted to a string using the implode() function. So probably you will need to add a couple of class plugins to convert the value to a string.

1
  • Yesssss! It works!!! It's exactley what i need it. Thanks a lot @MagestyApps
    – AcidBurn
    Nov 18 '21 at 10:56

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.