2

I'm working on a custom module. I need a admin config section with dynamic options. The idea is to have a list of all enabled shipping methods. Next to each method i need a select dropdown with shipping methods loaded from an external system. How can create an admin config section with dynamic data?

Ive created an screenshot to clear things up on what i need: enter image description here

I need a row for each enabled magento shipping method, and a dropdown next to it.

0

Try with below way.

Magento\Config\Block\System\Config\Form\Field\FieldArray\AbstractFieldArray class and override the _prepareToRender method in order to add columns to dynamic fields block, change “add button” label etc.

<?php

namespace Namespace\Modulename\Block\Adminhtml\Form\Field;

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

/**
 * Class AdditionalEmail
 */
class AdditionalEmail extends AbstractFieldArray
{
    /**
     * {@inheritdoc}
     */
    protected function _prepareToRender()
    {
        $this->addColumn('firstname', ['label' => __('First Name'), 'class' => 'required-entry']);
        $this->addColumn('lastname', ['label' => __('Last Name')]);
        $this->addColumn('email',['label' => __('Email'), 'size' => '50px', 'class' => 'required-entry validate-email']);
        $this->_addAfter = false;
        $this->_addButtonLabel = __('Add Email');
    }
}

The data is saved in one record of the core_config_data table in the database for each system configuration field. That’s why we need to serialize the data before saving and unserialize this value back after loading.

<?php

namespace Namespace\Modulename\Config\Backend;

use Magento\Framework\App\Cache\TypeListInterface;
use Magento\Framework\App\Config\ScopeConfigInterface;
use Magento\Framework\App\Config\Value as ConfigValue;
use Magento\Framework\Data\Collection\AbstractDb;
use Magento\Framework\Model\Context;
use Magento\Framework\Model\ResourceModel\AbstractResource;
use Magento\Framework\Registry;
use Magento\Framework\Serialize\SerializerInterface;

/**
 * Class AdditionalEmail
 */
class AdditionalEmail extends ConfigValue
{
    /**
     * Json Serializer
     *
     * @var SerializerInterface
     */
    protected $serializer;

    /**
     * ShippingMethods constructor
     *
     * @param SerializerInterface $serializer
     * @param Context $context
     * @param Registry $registry
     * @param ScopeConfigInterface $config
     * @param TypeListInterface $cacheTypeList
     * @param AbstractResource|null $resource
     * @param AbstractDb|null $resourceCollection
     * @param array $data
     */
    public function __construct(
        SerializerInterface $serializer,
        Context $context,
        Registry $registry,
        ScopeConfigInterface $config,
        TypeListInterface $cacheTypeList,
        AbstractResource $resource = null,
        AbstractDb $resourceCollection = null,
        array $data = []
    ) {
        $this->serializer = $serializer;
        parent::__construct($context, $registry, $config, $cacheTypeList, $resource, $resourceCollection, $data);
    }

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

        $this->setValue($encodedValue);
    }

    /**
     * Process data after load
     *
     * @return void
     */
    protected function _afterLoad()
    {
        /** @var string $value */
        $value = $this->getValue();
        $decodedValue = $this->serializer->unserialize($value);

        $this->setValue($decodedValue);
    }
}

etc/adminhtml/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="sample" translate="label" sortOrder="50">
            <label>Sample</label>
        </tab>
        <section id="test_sample" translate="label" type="text" sortOrder="10" showInDefault="1" showInWebsite="1" showInStore="1">
            <class>separator-top</class>
            <label>Test Sample</label>
            <tab>sample</tab>
            <resource>Namespace_Modulename::dynamic_fields</resource>
            <group id="additional" translate="label" type="text" sortOrder="10" showInDefault="1" showInWebsite="1" showInStore="1">
                <label>Additional</label>
                <field id="emails" translate="label" sortOrder="10" showInDefault="1" showInWebsite="1" showInStore="1">
                    <label>Additional Emails</label>
                    <frontend_model>Namespace\Modulename\Block\Adminhtml\Form\Field\AdditionalEmail</frontend_model>
                    <backend_model>Namespace\Modulename\Config\Backend\AdditionalEmail</backend_model>
                </field>
            </group>
        </section>
    </system>
</config>

For more information click here

I hope it helps!

  • 1
    Thank you for your anwser. I've tried the above earlier, but the problem is that i do not need text fields. I need a fixed value in the first column, and a select dropdown in second column. Do you know how to create that? – MartinE Mar 13 at 13:52
  • @MartinE have you found any solution? I am also looking to add drop down under system config. – Juliano Vargas Aug 5 at 11:41
  • @JulianoVargas unfortunately not. If I remember correctly, I solved my problem with a json config file in my case. So without the use of the admin panel. – MartinE Aug 6 at 12:18
  • @MartinE Ok, no worries I've manage to add it by overwriting renderCellTemplate method! – Juliano Vargas Aug 6 at 15:22

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.