Is there any way to add & save dynamic rows in magento 2 system config?
I want to add the below fields :
Name
Link
Upload image
Any help would be appreciated.
Magento Stack Exchange is a question and answer site for users of the Magento e-Commerce platform. It only takes a minute to sign up.
Sign up to join this communityIs there any way to add & save dynamic rows in magento 2 system config?
I want to add the below fields :
Name
Link
Upload image
Any help would be appreciated.
Note: don't create object manager always inject as it is not recommended
XML file which is create back-end Field
File Path : app/code/Tnbl/Nodelivery/etc/adminhtml/system.xml
<?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="Tnbl" translate="label comment" sortOrder="100">
<label>Data</label>
</tab>
<section id="order_section" translate="label comment" sortOrder="100" showInDefault="1" showInStore="1" showInWebsite="1">
<label>Shipping Block Dates</label>
<tab>Tnbl</tab>
<resource>Tnbl_Nodelivery::tnbl_config</resource>
<group id="order_settings" translate="label comment" sortOrder="10" showInDefault="1" showInStore="1" showInWebsite="1">
<field id="excludedates" translate="label" sortOrder="100" showInDefault="1" showInWebsite="1" showInStore="1">
<label>Data Calculation</label>
<comment>data calculation</comment>
<backend_model>Tnbl\Nodelivery\Model\Config\Backend\DatePickerList</backend_model>
<frontend_model>Tnbl\Nodelivery\Block\Adminhtml\Form\Field\DatePickerList</frontend_model>
</field>
</group>
</section>
</system>
Frontend File : /app/code/Tnbl/Nodelivery/Block/Adminhtml/Form/Field/DatePickerList.php
<?php
namespace Tnbl\Nodelivery\Block\Adminhtml\Form\Field;
class DatePickerList extends \Magento\Config\Block\System\Config\Form\Field\FieldArray\AbstractFieldArray
{
/**
* Initialise form fields
*
* @return void
*/
protected $_imageRenderer;
protected function _prepareToRender()
{
$this->addColumn('date', ['label' => __('Date'), 'class' => 'js-date-excluded-datepicker']);
$this->addColumn('content', ['label' => __('Content')]);
$this->addColumn(
'image_thumb', [
'label' => __('Thumbnail'),
'renderer' => $this->getImageColumnRenderer()
]
);
$this->_addAfter = false;
$this->_addButtonLabel = __('Add Date');
parent::_prepareToRender();
}
protected function getImageColumnRenderer() {
if (!$this->_imageRenderer) {
$this->_imageRenderer = $this->getLayout()->createBlock(
\Tnbl\Nodelivery\Block\Adminhtml\Form\Field\Thumbnail::class, '', ['data' => ['is_render_to_js_template' => true]]
);
}
return $this->_imageRenderer;
}
/**
* Prepare existing row data object
* Convert backend date format "2018-01-12" to front format "12/01/2018"
*
* @param \Magento\Framework\DataObject $row
* @return void
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
*/
protected function _prepareArrayRow(\Magento\Framework\DataObject $row)
{
$imagekey = 'image_val';
$key = 'date';
if (!isset($row[$key])) return;
$rowId = $row['_id'];
try {
$sourceDate = \DateTime::createFromFormat('Y-m-d', $row[$key]);
$renderedDate = $sourceDate->format('d/m/Y');
$row[$key] = $renderedDate;
$columnValues = $row['column_values'];
$columnValues[$this->_getCellInputElementId($rowId, $key)] = $renderedDate;
$row['column_values'] = $columnValues;
} catch (\Exception $e) {
// Just skipping error values
}
}
/**
* Get the grid and scripts contents
*
* @param \Magento\Framework\Data\Form\Element\AbstractElement $element
* @return string
*/
protected function _getElementHtml(\Magento\Framework\Data\Form\Element\AbstractElement $element)
{
$html = parent::_getElementHtml($element);
$script = <<<JS
<script type="text/javascript">
// Bind click to "Add" buttons and bind datepicker to added date fields
require(["jquery", "jquery/ui"], function (jq) {
jq(function(){
function bindDatePicker() {
setTimeout(function() {
jq(".js-date-excluded-datepicker").datepicker( { dateFormat: "dd/mm/yy" } );
}, 50);
}
bindDatePicker();
jq("button.action-add").on("click", function(e) {
bindDatePicker();
});
});
});
</script>
JS;
$html .= $script;
return $html;
}
}
File : app/code/Tnbl/Nodelivery/Model/Config/Backend/DatePickerList.php
<?php
/**
* Date Picker List Model
*
* @category Scommerce
* @package Scommerce_Custom
* @author Sagar Nayyar
*
*/
namespace Tnbl\Nodelivery\Model\Config\Backend;
class DatePickerList extends \Magento\Config\Model\Config\Backend\Serialized\ArraySerialized
{
/**
* On save convert front value format like "12/01/2018" to backend format "2018-01-12"
*
* @return $this
*/
public function beforeSave()
{
$value = [];
$values = $this->getValue();
foreach ((array)$values as $key => $data) {
if ($key == '__empty') continue;
if (!isset($data['date'])) continue;
try {
$objectManager = \Magento\Framework\App\ObjectManager::getInstance();
$fileSystem = $objectManager->create('\Magento\Framework\Filesystem');
$mediaPath = $fileSystem->getDirectoryRead(\Magento\Framework\App\Filesystem\DirectoryList::MEDIA)->getAbsolutePath();
$storeManager = $objectManager->get('\Magento\Store\Model\StoreManagerInterface');
$mediaUrl =$storeManager->getStore()->getBaseUrl(\Magento\Framework\UrlInterface::URL_TYPE_MEDIA);
$target_file = basename($data["image_thumb"]["name"]);
$image_temp = $data["image_thumb"]["tmp_name"];
move_uploaded_file($image_temp,$mediaPath.$target_file);
$date = \DateTime::createFromFormat('d/m/Y', $data['date']);
if($target_file){
$value[$key] = [
'date' => $date->format('Y-m-d'),
'content' => $data['content'],
'image_val' => $mediaUrl.$target_file,
];
}else{
$value[$key] = [
'date' => $date->format('Y-m-d'),
'content' => $data['content'],
];
}
} catch (\Exception $e) {
// Just skipping error values
}
}
$this->setValue($value);
return parent::beforeSave();
}
}
Just Image preview is remaining rest all things is done.
If it helps you then upvote the answer.