0

I'm trying to create a config table using ArraySerialized and I'm able to save it to database and retrieve it via code, the problem is everytime I load my backend panel, my custom select field from config table are always loading the first value.

I tried to follow some examples I saw online, but none seemed to work for me.

This is my code so far:

In system.xml

<field id="commands_list" showInDefault="1" showInStore="1" showInWebsite="1" sortOrder="16" translate="label comment tooltip" type="text">
    <label>Commands List</label>
    <backend_model>Magento\Config\Model\Config\Backend\Serialized\ArraySerialized</backend_model>
    <frontend_model>Werules\Chatbot\Block\Adminhtml\System\Config\Form\Field\Commands</frontend_model>
</field>

app\code\Werules\Chatbot\Block\Adminhtml\System\Config\Form\Field\CommandsSelect.php

<?php

namespace Werules\Chatbot\Block\Adminhtml\System\Config\Form\Field;

class CommandsSelect extends \Magento\Framework\View\Element\Html\Select
{
    /**
     * @var \Werules\Chatbot\Block\Adminhtml\System\Config\Form\Field\CommandsList
     */
    protected $_commandsList;

    public function __construct(
        \Werules\Chatbot\Block\Adminhtml\System\Config\Form\Field\CommandsList $commandsList,
        \Magento\Backend\Block\Template\Context $context, array $data = array())
    {
        parent::__construct($context, $data);
        $this->_commandsList = $commandsList;
    }

    public function _toHtml()
    {
        if (!$this->getOptions()) {
            foreach ($this->_commandsList->toOptionArray() as $option) {
                $this->addOption($option['value'], $option['label']);
            }
        }
        return parent::_toHtml();
    }

    public function getName()
    {
        return $this->getInputName();
    }
}

app\code\Werules\Chatbot\Block\Adminhtml\System\Config\Form\Field\CommandsList.php

<?php

namespace Werules\Chatbot\Block\Adminhtml\System\Config\Form\Field;

class CommandsList implements \Magento\Framework\Option\ArrayInterface
{
    /**
     * Provide available options as a value/label array
     *
     * @return array
     */
    public function toOptionArray()
    {
        return array(
            array('value' => 1, 'label' => __("List Categories")),
            array('value' => 2, 'label' => __("Search For Product"))
        );
    }
}

app\code\Werules\Chatbot\Block\Adminhtml\System\Config\Form\Field\Commands.php

<?php

namespace Werules\Chatbot\Block\Adminhtml\System\Config\Form\Field;

class Commands extends \Magento\Config\Block\System\Config\Form\Field\FieldArray\AbstractFieldArray
{
    /**
     * @var \Magento\Framework\Data\Form\Element\Factory
     */
    protected $_elementFactory;
    protected $_itemRendererCommands;
    protected $_itemRendererYesNo;

    /**
     * @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 = array()
    )
    {
        $this->_elementFactory  = $elementFactory;
        parent::__construct($context,$data);
    }
    protected function _construct()
    {
        $this->addColumn('command_id', array(
            'label' => __("Command"),
            'renderer' => $this->_getRendererCommands()
        ));
        $this->addColumn('enable_command', array(
            'label' => __("Enable Command"),
            'renderer' => $this->_getRendererYesNo()
        ));

        $this->_addAfter = false;
        $this->_addButtonLabel = __("Add");
        parent::_construct();
    }

    protected function _getRendererYesNo()
    {
        if (!$this->_itemRendererYesNo)
        {
            $this->_itemRendererYesNo = $this->getLayout()->createBlock(
                'Werules\Chatbot\Block\Adminhtml\System\Config\Options\YesNo',
                '',
                array('data' => array('is_render_to_js_template' => true))
//                array('is_render_to_js_template' => true)
            ); // ->setExtraParams('style="width: 100%;"');
        }
        return $this->_itemRendererYesNo;
    }

    protected function _getRendererCommands()
    {
        if (!$this->_itemRendererCommands)
        {
            $this->_itemRendererCommands = $this->getLayout()->createBlock(
                'Werules\Chatbot\Block\Adminhtml\System\Config\Form\Field\CommandsSelect',
                '',
                array('data' => array('is_render_to_js_template' => true))
//                array('is_render_to_js_template' => true)
            ); // ->setExtraParams('style="width: 100%;"');
        }
        return $this->_itemRendererCommands;
    }

    protected function _prepareArrayRow(\Magento\Framework\DataObject $row)
    {
        $optionExtraAttr = array();
        $optionExtraAttr['option_' . $this->_getRendererCommands()->calcOptionHash($row->getData('command_id'))] = 'selected="selected"';
        $row->setData(
            'option_extra_attrs', $optionExtraAttr
        );
        $optionExtraAttr = array();
        $optionExtraAttr['option_' . $this->_getRendererYesNo()->calcOptionHash($row->getData('enable_command'))] = 'selected="selected"';
        $row->setData(
            'option_extra_attrs', $optionExtraAttr
        );
    }
}

What am I doing wrong?

1

Oh boy... that was silly. I was rewriting the variable $optionExtraAttr assigning a new array to it with $optionExtraAttr = array();.

Well, fixed, not a Magento error at least.

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.