Hello Friends,
This blog becomes very interesting because we will see How to create one configuration field which contains multiple fields and held data in the database.
Sometimes, to create a similar type of field we need to create multiple configuration field but using the below technique you just need to create only a single configuration field and using frontend model we will create subfields which held the data and when you try to save it then it will store in the core_config_data table with serialize format.
Let’s see some easy steps to create this kind of field.
Step 1: First, create system configuration field in the following location
app/code/[Namespace]/[Module]/etc/adminhtml/system.xml
<field id="multiplefields" translate="label" sortOrder="10" showInDefault="1" showInWebsite="0" showInStore="0">
<label>Multiple Fields</label>
<frontend_model>[Namespace]\[Module]\Block\Adminhtml\Form\Field\MultipleFields</frontend_model>
<backend_model>[Namespace]\[Module]\Config\Backend\MultipleFields</backend_model>
</field>
In the above code, we are used frontend_model & backend_model
frontend_model: This block responsible for rendering the content of the columns in the table.
backend_model: This used for saving and loading data from DB as a serialized format.
Step 2: Create the frontend model in the following location
app/code/[Namespace]/[Module]/Block/Adminhtml/Form/Field/MultipleFields.php
<?php
namespace [Namespace]\[Module]\Block\Adminhtml\Form\Field;
use Magento\Config\Block\System\Config\Form\Field\FieldArray\AbstractFieldArray;
class MultipleFields extends AbstractFieldArray
{
protected function _prepareToRender()
{
$this->addColumn('firstbox', ['label' => __('First Text Field'), 'class' => 'required-entry']);
$this->addColumn('secondbox', ['label' => __('Second Text Field'), 'class' => 'required-entry']);
$this->_addAfter = false;
$this->_addButtonLabel = __('Add New');
}
}
In the above code, you can see that we have extends the \Magento\Config\Block\System\Config\Form\Field\FieldArray\AbstractFieldArray because we need table fields.
Here, we call _prepareToRender() function to declare out custom columns.
Step 3: Now, create the backend model in the following location
app/code/[Namespace]/[Module]/Config/Backend/MultipleFields.php
<?php
namespace [Namespace]\[Module]\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 MultipleFields 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();
if(isset($value)) {
$decodedValue = $this->serializer->unserialize($value);
$this->setValue($decodedValue);
}
}
}
In the above code, you need to create a backend model file that stores your data in core_config_table with serialize format.
Step 4: Get value from your field
We will create the function in Helper to get the value
<?php
namespace [Namespace]\[Module]\Helper;
use Magento\Framework\App\Helper\AbstractHelper;
use Magento\Store\Model\ScopeInterface;
use Magento\Framework\Serialize\SerializerInterface;
class Data extends AbstractHelper
{
protected $_scopeConfig;
protected $serializer;
public function __construct(
Context $context,
SerializerInterface $serializer
) {
parent::__construct($context);
$this->_scopeConfig = $context->getScopeConfig();
$this->serializer = $serializer;
}
public function getValueFromMultipleFields() {
$data = $this->_scopeConfig->getValue('SECTION/GROUP/FIELD',ScopeInterface::SCOPE_STORE);
$decodedValue = $this->serializer->unserialize($data);
foreach($decodedValue as $value) {
if($value['firstbox'] == 'Website 1') {
return $value['secondbox'];
}
}
return false;
}
}
Using the above code, now you just need to call your function from the helper to get the value that you want.
Thanks for reading this post!