2

How can i create table in system.xml file is there any way? I had searched around but can't find any solution enter image description here

want to create like this

13

2 Answers 2

3

Try like this:

In your system.xml file:

        <group id="your_id" translate="label" type="text" sortOrder="500" showInDefault="1" showInWebsite="1" showInStore="1">
            <label>My Label</label>             
            <field id="id_name" translate="label" sortOrder="410" showInDefault="1" showInWebsite="1" showInStore="1">
                <label>Sub Label</label>
                <frontend_model>NameSpace\ModuleName\Block\Adminhtml\System\Config\MyClass</frontend_model>
                <backend_model>NameSpace\ModuleName\Model\Config\Backend\MyClass</backend_model>
            </field>
        </group>

Explanation: NameSpace\ModuleName\Block\Adminhtml\System\Config\MyClass is responsible for showing you the table as you desire. NameSpace\ModuleName\Model\Config\Backend\MyClass is responsible to fill the data or save the data.

Now:

NameSpace\ModuleName\Block\Adminhtml\System\Config\MyClass.php:

<?php 
namespace NameSpace\ModuleName\Block\Adminhtml\System\Config;

class MyClass extends \Magento\Config\Block\System\Config\Form\Field\FieldArray\AbstractFieldArray
{
    /**
     * Prepare to render
     *
     * @return void
     */
    protected function _prepareToRender()
    {
        $this->addColumn('my_column', ['label' => __('Column 1')]);
        $this->addColumn('my_column_two', ['label' => __('Column 2')]);
        $this->_addAfter = false;
        $this->_addButtonLabel = __('Add Tab');
    }
}

NameSpace\ModuleName\Model\Config\Backend\MyClass.php:

<?php 
namespace NameSpace\ModuleName\Model\Config\Backend;
class MyClass extends \Magento\Framework\App\Config\Value
{
    
    /**
     * Process data after load
     *
     * @return void
     */
    protected function _afterLoad()
    {
        $value = $this->getValue();
        $arr = unserialize($value);

        $this->setValue($arr);
    }

    /**
     * Prepare data before save
     *
     * @return void
     */
    public function beforeSave()
    {
        $value = $this->getValue();
        unset($value['__empty']);
        $arr = serialize($value);
        
        $this->setValue($arr);
    }
}

UPDATE

According to the comments below, you may also use this:

<backend_model>Magento\Config\Model\Config\Backend\Serialized\ArraySerialized</backend_model>

instead of

<backend_model>NameSpace\ModuleName\Model\Config\Backend\MyClass</backend_model>

8
  • It works in my instance. Which php are you using? Any error logs (browser console, system/log)? May 8, 2019 at 6:07
  • Exception #0 (Exception): Notice: unserialize(): Error at offset 0 of 346 bytes in /var/www/m227/public_html/app/code/PME/STW/Block/Adminhtml/Form/Field/OptionField.php on line 16 "$arr = unserialize($value);" this line in backend
    – Asad Ullah
    May 8, 2019 at 6:09
  • i am using php 7.0
    – Asad Ullah
    May 8, 2019 at 6:09
  • That means, $this->getValue(); is not giving you right value. You should log that value and check if the value is serializable. May 8, 2019 at 6:12
  • 1
    Also, @AsadUllah was right, we should use <backend_model>Magento\Config\Model\Config\Backend\Serialized\ArraySerialized</backend_model> instead of custom <backend_model>
    – fudu
    Apr 14, 2021 at 9:37
0

After looking all files and errors this works for me combining two solutions in to one

System.xml file

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Config:etc/system_file.xsd">
<system>
    <tab id="wheelslicing" translate="label" sortOrder="10">
        <label>Spin wheel slice</label>
    </tab>
    <section id="slicing" translate="label" sortOrder="130" showInDefault="1" showInWebsite="1" showInStore="1">
        <class>separator-top</class>
        <label>Slice Setting</label>
        <tab>wheelslicing</tab>
        <resource>PME_STW::helloworld_config</resource>
        <group id="general" translate="label" type="text" sortOrder="10" showInDefault="1" showInWebsite="0" showInStore="0">
            <label>General Configuration</label>

                <field id="slice1" translate="label" type="text"
                       sortOrder="1" showInDefault="1" showInWebsite="0" showInStore="0">
                    <label>Display Text</label>
                    <comment>This text will display on the frontend.</comment>
                </field>
                 <field id="slice2" translate="label" type="text" sortOrder="1" showInDefault="1" showInWebsite="0" showInStore="0">
                        <label>Display Text</label>
                        <comment>This text will display on the frontend.</comment>
                    </field>
                 <field id="slice3" translate="label" type="text"
                    sortOrder="1" showInDefault="1" showInWebsite="0" showInStore="0">
                    <label>Display Text</label>
                    <comment>This text will display on the frontend.</comment>
                 </field>

            <field id="availability_map" translate="label" sortOrder="10" showInDefault="1" showInStore="1" showInWebsite="1">
                <label>Availability Map</label>
                <frontend_model>PME\STW\Block\Adminhtml\Form\Field\AvailabilityMap</frontend_model>
                <backend_model>Magento\Config\Model\Config\Backend\Serialized\ArraySerialized</backend_model>
            </field>

        </group>
    </section>
</system>

In PME\STW\Block\Adminhtml\Form\Field\AvailabilityMap

<?php
namespace PME\STW\Block\Adminhtml\Form\Field;

use \Magento\Config\Block\System\Config\Form\Field\FieldArray\AbstractFieldArray;
use \Magento\Framework\DataObject;

class AvailabilityMap extends AbstractFieldArray
{
protected $optionField;



  protected function _prepareToRender()
    {
//        $this->addColumn('availability_option', [
//            'label' => __('Availability Option'),
//            'renderer' => $this->getOptionField(),
//        ]);
        $this->addColumn('custom_availability_option', ['label' => __('Wheel Slice Value'), 'class' => 'required-entry']);
        $this->addColumn('custom_availability', ['label' => __('Reward'), 'class' => 'required-entry']);
        $this->_addAfter = false;
        $this->_addButtonLabel = __('Add Correlation');
    }

    /**
     * @return \SR\MagentoCommunity\Block\Adminhtml\Form\Field\OptionField
     */
    protected function getOptionField()
    {
        if (!$this->optionField) {
            $this->optionField = $this->getLayout()->createBlock(
                OptionField::class,
                '',
                ['data' => ['is_render_to_js_template' => true]]
            );
        }

        return $this->optionField;
    }

    /**
     * Prepare existing row data object
     *
     * @param DataObject $row
     * @return void
     */
    protected function _prepareArrayRow(DataObject $row)
    {
        $availabilityOption = $row->getAvailabilityOption();
        $options = [];
        if ($availabilityOption) {
            $options['option_' . $this->getOptionField()->calcOptionHash($availabilityOption)]
                = 'selected="selected"';
        }
        $row->setData('option_extra_attrs', $options);
    }

}

In your phtml file you will get this in json form decode it and use as u like

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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