zend-framework2zend-form2

How to format ZF2 DateSelect "day" element to 2 digits?


I am wanting to do a date of birth composite drop-down for date of birth (i.e. three drop-downs - one for day, one for month, one for year). Helpfully, ZF2 comes with this element built in, called DateSelect

Here is how I am adding it to the form:

    $this->add([
        'name' => 'date_of_birth',
        'type' => 'DateSelect',
        'attributes' => [
            'required' => true,
            'value' => date('Y-m-d', strtotime('18 years ago')),
        ],
        'options' => [
            'label' => 'Date of Birth',
            'max_year' => date('Y', strtotime('18 years ago')),
        ],
    ]);

To render the form I am doing:

echo $this->form($form);

Anyway, the day element is being rendered in j format (i.e. day of the month without leading zeros 1 to 31).

How do I tell the element to render the day in d format (i.e. day of the month, 2 digits with leading zeros 01 to 31)?


Solution

  • The view helper Zend\Form\View\Helper\FormDateSelect has a function getPattern that generates the patten by using the IntlDateFormatter class:

    $intl           = new IntlDateFormatter($this->getLocale(), $this->dateType, IntlDateFormatter::NONE);
    $this->pattern  = $intl->getPattern();
    

    There did not appear to be any method of setting a pattern at element level, so I have extended this view helper allowing me to specify my own pattern:

    <?php
    namespace RPK\Form\View\Helper;
    
    use Zend\Form\View\Helper\FormDateSelect as ZendFormDateSelect;
    
    class FormDateSelect extends ZendFormDateSelect
    {
        /**
         * Parse the pattern
         *
         * @param  bool $renderDelimiters
         * @return array
         */
        protected function parsePattern($renderDelimiters = true)
        {
            //Replace `day` value of "d" with "dd"
            $pattern = parent::parsePattern($renderDelimiters);
            if($pattern['day'] === 'd') {
                $pattern['day'] = 'dd';
            }
            return $pattern;
        }
    }
    

    Very basically, this takes the returned pattern array (['day'=>'d', 'month' => 'MMMM', 'year' => 'yyyy']), checks if the value of day is a single letter "d" and, if so, replaces it with a double-d.