2

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.

asked Apr 15, 2022 at 4:55
11
  • any thoughts on this ? Commented Apr 15, 2022 at 6:31
  • Are you need to create new grid with these fields or need to add in Store -> Configuration ? Commented Apr 15, 2022 at 8:42
  • Hello @Prits, I am trying to create it in Store -> Configuration. Commented Apr 15, 2022 at 8:47
  • Here is what I have tried - magento.stackexchange.com/questions/354870/…. Commented Apr 15, 2022 at 8:47
  • any thoughts on this ? Commented Apr 15, 2022 at 10:15

1 Answer 1

2

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.

answered Apr 18, 2022 at 7:37
13
  • Thank you very much @Prits. Can you please share an image? I just want to see how it looks like after the implementation. Commented Apr 18, 2022 at 7:53
  • Hello @Prits, where do I need to put the beforeSave() method in which file? Can you please send module if possible ? Commented Apr 18, 2022 at 7:55
  • the image is not visible, can it be fixed ? Commented Apr 18, 2022 at 8:00
  • 1
    @Devhs Added image yes sure will share with you wait for some time I have added beforeSave in Backend Model File. Commented Apr 18, 2022 at 8:00
  • 1
    Yes For Preview will look into it. Commented Apr 18, 2022 at 8:01

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.