Home » Php » php – How to globally set date format for Symfony forms?

php – How to globally set date format for Symfony forms?

Posted by: admin July 12, 2020 Leave a comment

Questions:

What’s the correct way to globally set custom date format for Symfony2 forms?

Default format is like Y-m-d, and if I enter date like m/d/Y or d/m/Y it’s treated as invalid.

Is there a way to somehow relate format to selected locale? I’m looking for simple solution without writing custom form types.

How to&Answers:

You can set the format in your FormType if you want another format.

$builder->add('date_created', 'date', array(
    'widget' => 'single_text',
    // this is actually the default format for single_text
    'format' => 'yyyy-MM-dd',
));

The default it not ‘Y-m-d’ its an instance of IntlDateFormatter. So that should select the correct locale if you don’t use single text.

type: integer or string default: IntlDateFormatter::MEDIUM (or
yyyy-MM-dd if widget is single_text)

http://symfony.com/doc/current/reference/forms/types/date.html#format
http://php.net/manual/en/class.intldateformatter.php

Answer:

You should be able to set this globally using an Event Listener http://symfony.com/doc/current/cookbook/form/dynamic_form_modification.html

Answer:

If you want to change the format of your date field depending on the locale, you’ll have to create a custom field and use it instead of date. It’s the only way that I’m aware of.

First, create the service and pass the locale in the arguments:

# src/Acme/DemoBundle/Resources/config/services.yml
services:
    acme_demo.form.type.localedate:
        class: Acme\DemoBundle\Form\Type\LocaleDateType
        arguments:
            - "%locale%"
        tags:
            - { name: form.type, alias: localedate }

Create the class with the code for the new field type. As you can see, it’s based on the field type date and changes the format depending on the current locale:

// src/Acme/DemoBundle/Form/Type/LocaleDateType.php
namespace Acme\DemoBundle\Form\Type;

use Symfony\Component\Form\AbstractType;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;

class LocaleDateType extends AbstractType
{
    private $locale;

    public function __construct($locale)
    {
        $this->locale = $locale;
    }

    public function setDefaultOptions(OptionsResolverInterface $resolver)
    {
        $resolver->setDefaults(array(
            'format' => $this->getFormat(),// return the format depending on locale
        ));
    }

    private function getFormat() {
        switch($this->locale) {
            case 'es':
                return 'dd-MM-yyyy';// return valid date format for this locale
            default:
                return 'yyyy-MM-dd';
        }
    }

    public function getParent()
    {
        return 'date';
    }

    public function getName()
    {
        return 'localedate';
    }
}

Use it in your application instead of the date field type:

$builder->add('date_created', 'localedate', array(
    'widget' => 'single_text',
));

Hope it helps.

Kind regards.

Answer:

You can override the date_widget of symfony under YourProjectFolder\vendor\symfony\symfony\src\Symfony\Bridge\Twig\Resources\views\Form\form_div_layout.html.twig.
Copy the file to another like fields.html.twig and put it under the global resource\views\Form\ and override the date_widget (change it to your default format):

{% block date_widget -%}
{% if widget == 'single_text' %}
    {{- block('form_widget_simple') -}}
{% else -%}
    <div {{ block('widget_container_attributes') }}>
        {{- date_pattern|replace({
            '{{ year }}':  form_widget(form.year),
            '{{ month }}': form_widget(form.month),
            '{{ day }}':   form_widget(form.day),
        })|raw -}}
    </div>
{%- endif %}

{%- endblock date_widget %}

Then in your form add :

{% form_theme form 'AAAYourBundle:Form:fields.html.twig'%}