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.

11
  • any thoughts on this ?
    – Devhs
    Apr 15 at 6:31
  • Are you need to create new grid with these fields or need to add in Store -> Configuration ?
    – Prits
    Apr 15 at 8:42
  • Hello @Prits, I am trying to create it in Store -> Configuration.
    – Devhs
    Apr 15 at 8:47
  • Here is what I have tried - magento.stackexchange.com/questions/354870/….
    – Devhs
    Apr 15 at 8:47
  • any thoughts on this ?
    – Devhs
    Apr 15 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.

13
  • Thank you very much @Prits. Can you please share an image? I just want to see how it looks like after the implementation.
    – Devhs
    Apr 18 at 7:53
  • Hello @Prits, where do I need to put the beforeSave() method in which file? Can you please send module if possible ?
    – Devhs
    Apr 18 at 7:55
  • the image is not visible, can it be fixed ?
    – Devhs
    Apr 18 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.
    – Prits
    Apr 18 at 8:00
  • 1
    Yes For Preview will look into it.
    – Prits
    Apr 18 at 8:01

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.