David Yell David Yell - 4 months ago 12
HTML Question

How to set custom names for datetime inputs generated by the form helper?

What you did



echo $this->Form->create(null, [
'type' => 'get',
'url' => ['controller' => 'Holidays', 'action' => 'calendar']
]);
echo $this->Form->month('month', ['empty' => 'Select month', 'value' => @$month]);
echo $this->Form->year('year', ['minYear' => date('Y'), 'maxYear' => 2020, 'empty' => 'Select year', 'value' => @$year]);


Expected Behavior



I was expecting that when a submit the form my resulting url would look like
example.com/holiday/calendar?month=03&year=2016


Actual Behavior



example.com/holidays/calendar?month%5Bmonth%5D=03&year%5Byear%5D=2016


First thought



So the first thought is to use the
name
option.

echo $this->Form->month('month', ['name' => 'foo', 'empty' => 'Select month', 'value' => @$month]);


Which will produce
<select name="foo[month]"..
which has the same issue.

Second thought



Customise the form input template. This doesn't allow customisation of the name token as it's passed as
{{name}}
so by the time it's got to the template it's too late.

Third thought



Use the array and name the fields the same.

echo $this->Form->month('month', ['name' =>'when', 'empty' => 'Select month', 'value' => @$month]);
echo $this->Form->year('year', ['name' => 'when', 'minYear' => date('Y'), 'maxYear' => 2020, 'empty' => 'Select year', 'value' => @$year]);


I would then expect
example.com/holidays/calendar?when[month]=03&when[year]=2016
, but you actually get
/holidays/calendar?when%5Bmonth%5D=02&when%5Byear%5D=2016


Conclusion



So unfortunately with three different approaches I've not been able to solve this use-case. I'd be interested if anyone knows how to customise the html name attribute generated by the form helper, or prevent get forms from being escaped, so that my urls don't look so messy.

ndm ndm
Answer

Whether the URL is being displayed encoded or not, depends on your browser. Firefox will for example display it unencoded, while Chromes shows it encoded.

The date widget uses nested names, so that the date/time parser for date/time columns receives everything it needs for parsing and constructing objects from it.

With how the date widget currently works, there is no way to change the way the name is built. What you could do is for example using a custom select template for that input, or create a select type input with the necessary options on your own.

You've probably tried the former with global templates, which is why it failed. You need to use local ones, and consequently you'll have to use FormHelper::input() in order for the form helper to use them, like

echo $this->Form->input('month', [
    'type' => 'month',
    'empty' => 'Select month',
    'value' => @$month,
    'templates' => [
        'select' => '<select name="month"{{attrs}}>{{content}}</select>'
    ]
]);
echo $this->Form->input('year', [
    'type' => 'year',
    'minYear' => date('Y'),
    'maxYear' => 2020,
    'empty' => 'Select year',
    'value' => @$year,
    'templates' => [
        'select' => '<select name="year"{{attrs}}>{{content}}</select>'
    ]
]);