1

I need to add option to select multiple dates in system configure. I can add single date input field in system configure. but I doesn't have any idea about to add multi date picker in system configure.

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>
 <section id="carriers" translate="label" type="text" sortOrder="320" showInDefault="1" showInWebsite="1" showInStore="1">
 <group id="customshippingmethod" translate="label" type="text" sortOrder="900" showInDefault="1" showInWebsite="1" showInStore="1">
 <label>Custom Shipping Method</label>
 <field id="active" translate="label" type="select" sortOrder="10" showInDefault="1" showInWebsite="1" showInStore="0" canRestore="1">
 <label>Enabled</label>
 <source_model>Magento\Config\Model\Config\Source\Yesno</source_model>
 </field>
 <field id="from_date" translate="label" type="date" sortOrder="15" showInDefault="1" showInWebsite="1"
 showInStore="1">
 <label>From</label>
 <!-- Here we pass class where we create date picker-->
 <frontend_model>Vendor\ModuleName\Block\DatePicker</frontend_model>
 </field>
 </group>
 </section>
 </system>
</config>

Vendor\ModuleName\Block\DatePicker File

<?php
namespace Vendor\ModuleName\Block;
class DatePicker extends \Magento\Config\Block\System\Config\Form\Field
{
 public function render(\Magento\Framework\Data\Form\Element\AbstractElement $element)
 {
 $element->setDateFormat(\Magento\Framework\Stdlib\DateTime::DATE_INTERNAL_FORMAT);
 $element->setTimeFormat('HH:mm:ss'); //set date and time as per your need
 $element->setShowsTime(true);
 return parent::render($element);
 }
}

see below Image to understand exactly what I have to achieve

enter image description here

asked Jul 19, 2022 at 12:56

2 Answers 2

1

Add in your system.xml

<field id="dynamic_field_holidays" translate="label" sortOrder="4" showInDefault="1" showInWebsite="1" showInStore="1">
 <label>Holidays/Exclude Days/Blackout Days</label> 
 
 <backend_model>Vendor\Module\Block\Adminhtml\Config\Backend\Datepicker</backend_model>
 <frontend_model>Vendor\Module\Block\Adminhtml\Datepicker</frontend_model>
</field>

Create Datepicker.php file at Vendor\Module\Block\Adminhtml\Config\Backend

<?php
namespace Vendor\Module\Block\Adminhtml\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 Datepicker extends ConfigValue
{
 protected $serializer;
 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);
 }
 public function beforeSave()
 {
 $value = $this->getValue();
 if (isset($value['__empty'])) {
 unset($value['__empty']);
 }
 $encodedValue = $this->serializer->serialize($value);
 $this->setValue($encodedValue);
 }
 protected function _afterLoad()
 {
 $value = $this->getValue();
 if ($value) {
 $decodedValue = $this->serializer->unserialize($value);
 $this->setValue($decodedValue);
 }
 }
}

Create Datepicker.php file at Vendor\Module\Block\Adminhtml

<?php
namespace Vendor\Module\Block\Adminhtml;
use Magento\Backend\Block\Template\Context;
use Magento\Config\Block\System\Config\Form\Field\FieldArray\AbstractFieldArray;
use Magento\Framework\DataObject;
use Magento\Framework\Registry;
class Datepicker extends AbstractFieldArray
{
 private $holidaysRenderer;
 private $dateRenderer;
 public function __construct(
 Context $context,
 Registry $coreRegistry,
 array $data = []
 ) {
 $this->_coreRegistry = $coreRegistry;
 parent::__construct($context, $data);
 }
 protected function _prepareToRender()
 {
 $this->addColumn(
 'select_date',
 [
 'label' => __('Date'),
 'id' => 'select_date',
 'class' => 'daterecuring',
 'style' => 'width:200px'
 ]
 );
 $this->addColumn(
 'date_title',
 [
 'label' => __('Content'),
 'class' => 'required-entry',
 'style' => 'width:300px',
 ]
 );
 $this->_addAfter = false;
 $this->_addButtonLabel = __('MoreAdd');
 }
 protected function _prepareArrayRow(DataObject $row): void
 {
 $options = [];
 $row->setData('option_extra_attrs', $options);
 }
 protected function _getElementHtml(\Magento\Framework\Data\Form\Element\AbstractElement $element)
 {
 $html = parent::_getElementHtml($element);
 $script = '<script type="text/javascript">
 require(["jquery", "jquery/ui", "mage/calendar"], function (jq) {
 jq(function(){
 function bindDatePicker() {
 setTimeout(function() {
 jq(".daterecuring").datepicker( { dateFormat: "mm/dd/yy" } );
 }, 50);
 }
 bindDatePicker();
 jq("button.action-add").on("click", function(e) {
 bindDatePicker();
 });
 });
 });
 </script>';
 $html .= $script;
 return $html;
 }
}
answered Jul 19, 2022 at 13:17
1
  • Thank you for solution. your solution is also worked. you answer & my answer almost same. just difference is using my answer it save date in standard Y-m-d format. & using your answer it save the date in d/m/Y format. Commented Jul 20, 2022 at 5:57
0

I found solution. I share that solution with community I hope this one is helped to you.

system.xml file

<field id="exclude_days" translate="label" sortOrder="20" showInDefault="1" showInWebsite="1" showInStore="0">
 <label>Exclude Days</label>
 <frontend_model>Vendor\ModuleName\Block\System\Config\Form\Field\ExcludeDaysMultipleFields</frontend_model>
 <backend_model>Vendor\ModuleName\Model\Config\Backend\ExcludeDaysMultipleFields</backend_model>
</field>

ExcludeDaysMultipleFields fronend Model created at Vendor\ModuleName\Block\System\Config\Form\Field path

<?php
 
namespace Vendor\ModuleName\Block\System\Config\Form\Field;
use Magento\Config\Block\System\Config\Form\Field\FieldArray\AbstractFieldArray;
 
class ExcludeDaysMultipleFields extends AbstractFieldArray
{
 protected function _prepareToRender()
 {
 $this->addColumn('date', ['label' => __('Date'), 'class' => 'js-date-excluded-datepicker']);
 $this->addColumn('content', ['label' => __('content'), 'class' => 'required-entry']); 
 $this->_addAfter = false;
 $this->_addButtonLabel = __('Add Date');
 parent::_prepareToRender();
 }
 /**
 * Prepare existing row data object
 * Convert backend date format "2022年01月12日" to front format "12/01/2022"
 *
 * @param \Magento\Framework\DataObject $row
 * @return void
 * @SuppressWarnings(PHPMD.UnusedFormalParameter)
 */
 protected function _prepareArrayRow(\Magento\Framework\DataObject $row)
 {
 $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;
 }
}

ExcludeDaysMultipleFields backend model created at Vendor\ModuleName\Model\Config\Backend path

<?php
namespace Vendor\ModuleName\Model\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 ExcludeDaysMultipleFields extends \Magento\Config\Model\Config\Backend\Serialized\ArraySerialized
{
 /**
 * 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);
 }
 /**
 * 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 {
 $date = \DateTime::createFromFormat('d/m/Y', $data['date']);
 $value[$key] = [
 'date' => $date->format('Y-m-d'),
 'content' => $data['content'],
 ];
 } catch (\Exception $e) {
 // Just skipping error values
 }
 }
 $encodedValue = $this->serializer->serialize($value);
 $this->setValue($encodedValue);
 return parent::beforeSave();
 }
}

Output

output image

answered Jul 19, 2022 at 12:56
1

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.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.