DataTransformer - splits DateTime into two fields

I recently created a DataTransformer which at the end will accept various date formats (e.g. 12/12/2012 or 12.12.2012 or 2012-12-12).

My question is : before the date and time were divided into two different fields:

 $builder->add('date_end', 'datetime', array( 'label' => 'Date/Time', 'date_widget' => 'single_text', 'time_widget' => 'single_text', 'date_format' => 'dd.MM.yyyy', 'with_seconds' => false, 'required' => false, ) ) 

This worked fine. How can I accomplish this with the new DataTransformer ?

Inside my entity type:

 public function buildForm(FormBuilder $builder, array $options) { builder->add('date_end', 'dateTime', array( 'label' => 'Date/Time', 'required' => false, ) ) } 

The corresponding DateTimeType type I created is:

 class DateTimeType extends AbstractType { private $om; public function __construct(ObjectManager $om) { $this->om = $om; } public function buildForm(FormBuilder $builder, array $options) { $transformer = new DateTimeTransformer($this->om); $builder->appendClientTransformer($transformer); } public function getDefaultOptions(array $options) { return array( 'invalid_message' => 'TODO INVALID', ); } public function getParent(array $options) { return 'text'; } public function getName(){ return 'dateTime'; } } 

My transformer so far:

 /** * @param \DateTime|null $dateTime * @return string|null */ public function transform($dateTime) { if (null === $dateTime) { return null; } return $dateTime->format('Ymd H:i'); } /** * @param string $value * @return string|null */ public function reverseTransform($value) { if ( (null === $value) || empty($value) ) { return null; } return new \DateTime( $value ); } 
+3
source share
1 answer

I assume you are using Symfony 2.0. I read that the form component has changed a bit in 2.1.

I had a similar problem - I wanted to have a datetime field that uses separate widgets to enter the date and time (hour).

First of all, you need to create a separate type of form for this field (which is actually a form in itself).

My code is similar to this (modified for this example):

 class MyDateTimeType extends AbstractType { public function buildForm(FormBuilder $builder, array $options) { $builder ->add('date', 'date', array( 'label' => 'label.form.date', 'input' => 'datetime', 'widget' => 'single_text', 'format' => 'yyyy-MM-dd', 'error_bubbling' => true )) ->add('time', 'time', array( 'label' => 'label.form.time', 'input' => 'datetime', 'widget' => 'choice', 'error_bubbling' => true )); $builder->appendClientTransformer(new DateTimeToDateTimeArrayTransformer()); } public function getDefaultOptions(array $options) { return array( 'label' => 'label.form.date', 'error_bubbling' => false ); } public function getParent(array $options) { return 'form'; } public function getName() { return 'my_datetime'; } } 

As you can see, this is a form (do not confuse it), but we will use it as one logical field. The one that includes the data converter. It must split one instance of DateTime by date and time to obtain data for two subfields when the form is displayed and vice versa when the form is submitted.

The error_bubbling parameters ensure that errors generated by subfields join our new subfield and do not propagate to the top-level form, but you may have a great goal.

My data converter looks like this:

 class DateTimeToDateTimeArrayTransformer implements DataTransformerInterface { public function transform($datetime) { if(null !== $datetime) { $date = clone $datetime; $date->setTime(12, 0, 0); $time = clone $datetime; $time->setDate(1970, 1, 1); } else { $date = null; $time = null; } $result = array( 'date' => $date, 'time' => $time ); return $result; } public function reverseTransform($array) { $date = $array['date']; $time = $array['time']; if(null == $date || null == $time) return null; $date->setTime($time->format('G'), $time->format('i')); return $date; } } 

Finally, you can use it like this:

 $builder->add('startDate', 'my_datetime', array( 'label' => 'label.form.date' )); 

You must register it as a service in order to use it by an alias, otherwise execute it directly ( new MyDateTimeType() ).

This may not be the nicest solution, but it is also a form component in Symfony 2.0.

+2
source

All Articles