5

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.

4
  • Do you mean a date to be entered in the admin section of the widget or the front end? Jan 23, 2014 at 16:11
  • When you choose a widget, a date needs to be selected as widget parameter. So, in admin section, yes.
    – LDusan
    Jan 23, 2014 at 16:32
  • Can you please explain a little bit more, what you are talking about? Maybe add a screenshot. Jan 23, 2014 at 17:53
  • Sure: postimg.org/image/e31ldikmj. Below "Block* Not selected", I want "Date:" and datepicker.
    – LDusan
    Jan 23, 2014 at 18:33

4 Answers 4

3

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.

1
  • @LDusan. No problem. Sorry I couldn't give you a 100% working solution.
    – Marius
    Feb 3, 2014 at 7:48
2

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;
    }
}
2

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;
    }
}
1

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')

Datepicker looks like: enter image description here

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.