Symfony2 Forms have a rich set of field types and many defined widgets for rendering fields. But still we may need a different representation of a field. For example, in a web application of today we cannot think of a date field without a datepicker.
Symfony2 Forms don’t have any built in widget for rendering a date field with a datepicker. But, Symfony Form’s customization options are so flexible that, actually there is nothing to be worry about. Just in few minutes, using a simple trick, we can turn our date filed into a datepicker. In this post, I am going to share the trick with an example.
To demonstrate this idea, first we need a rendered Symfony Form with a date field. If you don’t have it already, please quickly go through Step 1 and Step 2 of previous post about Symfony2 Forms. We’ll now discuss about how to render the date field with a datepicker instead of 3 dropdowns. It’s just 3 tasks.
Although we are discussing only date field here, same idea can be implemented for datetime or any other field that we want to render with a javascript widget.
Step 1. Include a JavaScript Datepicker
Let’s choose a beautiful javascript datepicker first. For our example, I am choosing bootstrap-datepicker. It’s lightweight, easy to use and looks cool with twitter bootstrap. Because of rich data-api, it’s very easy to use with Symfony Forms.
So, if you don’t already have any other javascript datepicker included, let’s include this library –
- Download this library from github.
- Place it in
Resources/public/plugins/
directory of your Bundle or in/app
. - Include the
js/bootstrap-datepicker.js
andcss/datepicker.css
files of this plugin in your layout.
See how to do it if you’ve any confusion.
Step 2. Render the date field as text input
Just add the following options to date filed –
// ->add('dueDate', 'date')
->add('dueDate', 'date', ['widget' => 'single_text', 'format' => 'dd-MM-yyyy'])
Now the dueDate field will be rendered as a text input. And, after submission of the form, Symfony will expect the date as dd-MM-yyyy
(this is the default) format. For more information on valid formats, see Date/Time Format Syntax.
Step 3. Instantiate datepicker with this text input
This step may vary based on the javascript widget we are using. For our case, bootstrap-datepicker provides data-attributes
for instantiating and configuring datepicker on a target element. Let’s set proper attributes on our dueDate field –
// ->add('dueDate', 'date', ['widget' => 'single_text', 'format' => 'dd-MM-yyyy'])
->add('dueDate', 'date', [
'widget' => 'single_text',
'format' => 'dd-MM-yyyy',
'attr' => [
'class' => 'form-control input-inline datepicker',
'data-provide' => 'datepicker',
'data-date-format' => 'dd-mm-yyyy'
]
]
Here, using the data-provide
attribute we are instructing to instantiate a datepicker on this text field and using data-date-format
to set the date format to Symfony’s expected pattern. If you change the date format, remember to change data-date-format
attribute and format
options respectively. Check the full list of configuration options. You’ll surely be amazed with the completeness of option set.
If your datepicker library do not provide data-attributes like this example, you can use the datepicker
class (we’ve set in line 6) to select dueDate field in javascript.
We’re Done! It was easy, right?
Nice tutorial ! Thanx a lot Anis.
You are welcome 🙂
Wow
Nice and clear to follow, love how short it is!!
Anyhow, is there a way to include time? Not only dates.
Thanks 🙂
Yes, you can add time using the same technique. You just need to choose a plugin that supports date-time picker which have similar data-attributes for setting options. Otherwise, you have to configure and activate it from javascript.
BTW, this bootstrap datepicker don’t support time.
Nice tutorial simple one
how to Change language to Bootstrap Datetimepicker(spanish)
Here is how to do it – http://bootstrap-datepicker.readthedocs.io/en/stable/i18n.html
Thanks.
Hi Anis, I am running to a couple of issues:
1- I don’t get the mouse hover effect on single cell, though the entire row turns grey on mouse hover.
2- When I click outside the calendar it doesn’t get closed, precisely it will close only if I click on the upper or lower empty area of the calendar. It won’t close if I click on the empty area on the right side of the calendar.
3- How can I add a calendar icon next to the selected date?
Thanks
1+2. It’s hard to comment without seeing, sorry 🙁
3. To show calendar use bootstrap input-group. See code when you change Type to component here.
Hello, I cant make work the datepicker with component, could you please give me a clue?
Hi,
Nice tuto 🙂
Thank you
Hi, thanks for the explanation.
One question,
how can I set the default date into the datepciker to current date, for example?
Thanks
By default, today should remain selected automatically.
If you want to change, here is how to do – http://bootstrap-datepicker.readthedocs.io/en/stable/options.html#id3
Sorry for late reply 🙂
hello thx for this clear tuto , but i got this problem: Parse Error: syntax error, unexpected ‘[‘ (in line 2 in your example) , any idea plz ?
Hey,
How do I change the starting date, for over 18 limitation [first available date for selection should be today – 18 years]?
While at it, how do I limit the end date [lets say for 120 years]?
Thanks
Please check the
startDate
andendDate
options here – http://bootstrap-datepicker.readthedocs.io/en/stable/options.html#id6Thanks, it worked perfectly. But now I need to implement a bootstrap timepicker in a symfony form? I looked for but I didn´t found nothing. Can anyone help me?? Thanks so much.
Thanks for asking. Please check the comment above –
http://ajaxray.com/blog/symfony2-forms-bootstrap-3-datepicker-for-date-field/#comment-54625
Thanks for this post.
For Symfony3 is necessary add this code:
use Symfony\Component\Form\Extension\Core\Type\DateType;
And change this code:
->add(‘fechaInicio’, DateType::class, array(
‘label’ => ‘Fecha de Inicio’,
‘widget’ => ‘single_text’,
‘attr’ => array(
‘class’ => ‘form-control input-inline datepicker’,
‘data-provide’ => ‘datepicker’,
‘data-date-format’ => ‘yyyy-mm-dd’
)
)
)
Regards