In my application, the user hsa to give a date by only selecting a month and a year in two dropdown lists. How can I achieve that?
Here is what I've tried so far :
In my Form :
$builder->add('date1', 'date', array(
'widget' => 'choice',
'empty_value' => '',
'format' => 'MMMM-yyyy',
'input' => 'datetime',
'years' => range(date('Y'), date('Y') - 30, -1)
)
which actually works and displays it exactly as I want but when validating the form, I get an error :
This value is not valid
A screenshot of the wanted result :
@Oleg was pretty close to the correct answer. You have to use a view transformer to make sure that the DateTime gets a day.
/* In your formType.php */
$builder->add(
$builder->create('date1', 'date', array(
'format' => 'MMMM-yyyyd', // you need to have 'y', 'M' and 'd' here
'years' => range(date('Y'), date('Y') - 30, -1)
))
->addViewTransformer(new IncompleteDateTransformer()));
)
Create a transformer:
class IncompleteDateTransformer implements DataTransformerInterface
{
/**
* Do nothing when transforming from norm -> view
*/
public function transform($object)
{
return $object;
}
/**
* If some components of the date is missing we'll add those.
* This reverse transform will work when month and/or day is missing
*
*/
public function reverseTransform($date)
{
if (!is_array($date)) {
return $date;
}
if (empty($date['year'])) {
return $date;
}
if (empty($date['day'])) {
$date['day']=1;
}
if (empty($date['month'])) {
$date['month']=1;
}
return $date;
}
}
Create a twig template where you use a custom form theme from the file itself:
{# example.html.twig #}
{% form_theme form _self %}
{% block date_widget %}
{% spaceless %}
{% if widget == 'single_text' %}
{{ block('field_widget') }}
{% else %}
<div {{ block('widget_container_attributes') }}>
<div class="datetime_widget">
{{ date_pattern|replace({
'{{ year }}': form_widget(form.year),
'{{ month }}': form_widget(form.month),
'{{ day }}': '',
})|raw }}
</div>
</div>
{% endif %}
{% endspaceless %}
{% endblock date_widget %}
<h2>Select a date</h2>
{{ form(form) }}
References:
Example for credit card expiration date:
$builder->add('expirationDate', 'date', array(
'label' => 'Expiration date',
'widget' => 'choice',
'empty_value' => array('year' => 'Year', 'month' => 'Month', 'day' => 'Day'),
'format' => 'dd-MM-yyyy',
'input' => 'string',
'data' => date('Y-m-d'),
'years' => range(date('Y'), date('Y') + 10),
));
Then you must render this field manually.
Your form's twig template:
{{ form_row(form.expirationDate, {'date_pattern': '<span style="display: none;">{{ day }}</span> {{ month }} <span class="delim">/</span> {{ year }}'}) }}
Overriding date_pattern
will hide day select. You will get month / year format.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With