What is the best way to create widget with a parameter with date picker?
The problem is that I did not find a good way to supply format value to Date element class.
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 communityWhat is the best way to create widget with a parameter with date picker?
The problem is that I did not find a good way to supply format value to Date element class.
Date fields don't work in widgets mainly because of this: Mage_Widget_Block_Adminhtml_Widget_Options::_addField()
- this is the method that renders the options.
The date for the widget option looks like this:
$data = array(
'name' => $form->addSuffixToName($fieldName, 'parameters'),
'label' => $this->_translationHelper->__($parameter->getLabel()),
'required' => $parameter->getRequired(),
'class' => 'widget-option',
'note' => $this->_translationHelper->__($parameter->getDescription()),
);
So even if you specify a format in your xml it will be ignored.
Rewrite the method above and add change the code above to:
$data = array(
'name' => $form->addSuffixToName($fieldName, 'parameters'),
'label' => $this->_translationHelper->__($parameter->getLabel()),
'required' => $parameter->getRequired(),
'class' => 'widget-option',
'note' => $this->_translationHelper->__($parameter->getDescription()),
);
if ($parameter->getType() == 'date') {
'format' => $parameter->getFormat(),
'image' => $this->getSkinUrl('images/grid-cal.gif'),
}
And this still won't get it to work. I mean the field will appear but the calendar doesn't work. I haven't figured out yet why.
I inserted the datepicker with little trick:
Inside widget.xml:
<to_date>
<label>Date</label>
<visible>1</visible>
<required>1</required>
<type>text</type>
<helper_block>
<type>Namespace_Module_Block_Adminhtml_Widget_Date</type>
</helper_block>
</to_date>
Block file:
class Namespace_Module_Block_Adminhtml_Widget_Date extends Mage_Adminhtml_Block_Widget_Grid
{
public function __construct($arguments=array())
{
parent::__construct($arguments);
}
public function prepareElementHtml(Varien_Data_Form_Element_Abstract $element)
{
//var_dump($this->getSkinUrl('images/grid-cal.gif')); exit;
$form = new Varien_Data_Form(array(
'id' => 'edit_form',
'action' => '',
'method' => 'post'
));
$element2 = new Varien_Data_Form_Element_Date(
array(
'name' => 'date',
'label' => Mage::helper('module')->__('Date'),
'after_element_html' => '<small>Click icon to select</small>',
'tabindex' => 1,
'type' => 'datetime',
'time'=>true,
'image' => $this->getSkinUrl('images/grid-cal.gif'),
'format' => 'yyyy-MM-dd HH:mm:ss',
'value' => date(
'yyyy-MM-dd HH:mm:ss',
strtotime('next weekday')
)
)
);
$element2->setForm($form);
$id = 'date'.$element->getHtmlId();
$element2->setId($id);
$html = $element2->getElementHtml();
$html .= "
<style>
.calendar{z-index:999999;}
#$id{display:none}
</style>
<script>
var element = jQuery('#".$element->getHtmlId()."');
element.attr('style', 'width: 150px !important');
jQuery('body').on('change', '#$id', function(e) {
element.val(jQuery(this).val())
});
jQuery('#{$id}_trig').on('click', function() {
setTimeout(function(){
jQuery('.calendar').css('top',(parseInt(element.offset().top)-50)+'px')
jQuery('.calendar').css('left',(parseInt(element.offset().left)-150)+'px')
}, 100);
});
</script>";
$element->setData('after_element_html', $html);
return $element;
}
}
Simply add following code to your widget ....
Namespace/Module/etc/widget.xml
<?xml version="1.0"?>
<widgets>
<namespacemodule type="core/template" translate="name description">
<from_date>
<label>Date</label>
<visible>1</visible>
<required>1</required>
<type>date</type>
<helper_block>
<type>namespacemodule/adminhtml_widget_date</type>
</helper_block>
</from_date>
...
Namespace/Module/Block/Adminhtml/Widget/Date.php
<?php
class Namespace_Module_Block_Adminhtml_Widget_Date extends Mage_Adminhtml_Block_Widget_Grid {
public function __construct($arguments = array()) {
parent::__construct($arguments);
}
public function prepareElementHtml(Varien_Data_Form_Element_Abstract $element) {
$element->setFormat('yyyy-MM-dd');
$element->setImage($this->getSkinUrl('images/grid-cal.gif'));
return $element;
}
}
In Magento 2 it works in this way
Namespace/Module/etc/widget.xml:
<parameter name="display_from" xsi:type="block" required="true" visible="true" sort_order="40">
<label translate="true">Display from</label>
<block class="Namespace\Module\Block\Widget\Type\DatePicker">
</block>
</parameter>
Namespace/Module/Block/Widget/Type/DatePicker.php:
<?php
namespace Namespace\Module\Block\Widget\Type;
use Magento\Backend\Block\{
Template,
Template\Context,
};
use Magento\Framework\Data\Form\{
Element\AbstractElement,
Element\Factory,
};
use Magento\Framework\Exception\LocalizedException;
class DatePicker extends Template
{
/**
* @var Factory
*/
private $elementFactory;
/**
* DatePicker constructor.
*
* @param Context $context
* @param Factory $elementFactory
* @param array $data
*/
public function __construct(
Context $context,
Factory $elementFactory,
$data = []
) {
$this->elementFactory = $elementFactory;
parent::__construct($context, $data);
}
/**
* @param AbstractElement $element
*
* @return AbstractElement
* @throws LocalizedException
*/
public function prepareElementHtml(AbstractElement $element): AbstractElement
{
/** @var \Magento\Framework\Data\Form\Element\Text $input */
$input = $this->elementFactory->create("text", ['data' => $element->getData()]);
$input->setId($element->getId());
$input->setForm($element->getForm());
$input->addCustomAttribute('style', 'width: auto');
$input->setClass('widget-option input-text admin__control-text');
if ($element->getRequired()) {
$input->addClass('required-entry');
}
$calendarScript = '
<script>require([
"jquery",
"mage/translate",
"mage/calendar"
], function ($, $t) {
$("#' . $element->getId() . '").calendar({
changeMonth: true,
changeYear: true,
showButtonPanel: true,
currentText: $t("Go Today"),
closeText: $t("Close")
});
})</script>';
$element->setData('after_element_html', $input->getElementHtml() . $calendarScript);
$element->setValue('');
return $element;
}
}
You can get data of this parameter in your Blocks in this way:
$this->getData('display_from')