Symfony2 custom time selection field

I am trying to create custom date and time form fields. As in this answer , I have a date-time split field with one date form field and a time form field using a DataTransformer.

I use jQuery datepicker to select a date, but I want to have one select form field to select a time with an hour and a half interval:

00:00 00:30 ... 23:30 

Here is my code, but I'm not sure how to approach this

In my essence

 /** * Time * * @ORM\Table(name="time") * @ORM\Entity */ class Time { ... /** * @var \DateTime * * @ORM\Column(name="begin_date", type="datetime", nullable=false) */ private $beginDate; /** * @var \DateTime * * @ORM\Column(name="end_date", type="datetime", nullable=false) */ private $endDate; ... /** * Set beginDate * * @param \DateTime $beginDate * @return Time */ public function setBeginDate($beginDate) { $this->beginDate = $beginDate; return $this; } /** * Get beginDate * * @return \DateTime */ public function getBeginDate() { $this->beginDate; } /** * Set endDate * * @param \DateTime $endDate * @return Time */ public function setEndDate($endDate) { $this->endDate = $endDate; return $this; } /** * Get endDate * * @return \DateTime */ public function getEndDate() { return $this->endDate; } ... } 

Type of form

 class TimeType extends AbstractType { public function buildForm(FormBuilderInterface $builder, array $options) { $builder ->add('beginDate', 'my_datetime', array('label' => 'label.form.date')) ->add('endDate', 'my_datetime', array('label' => 'label.form.date')); } public function getName() { return 'Time'; } } 

So here is my custom form type:

  class MyDateTimeType extends AbstractType { public function buildForm(FormBuilderInterface $builder, array $options) { $builder ->add('date', 'genemu_jquerydate', array('input' => 'datetime','widget' => 'single_text','format' => 'dd/MM/yyyy','error_bubbling' => true)) ->add('time', 'choice', array( 'choices' => array( '00:00' => '00:00', '00:30' => '00:30', '01:00' => '01:00', ... '22:30' => '22:30', '23:00' => '23:00', '23:30' => '23:30', ),'error_bubbling' => true )); $builder->appendClientTransformer(new DateTimeToDateTimeArrayTransformer()); } public function getDefaultOptions(array $options) { return array( 'label' => 'label.form.date', 'error_bubbling' => false ); } public function getName() { return 'my_datetime'; } } 

And this is a DataTransformer:

 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']; // Fatal error: Call to a member function format() on a non-object $time = new \DateTime($array['time']); if(null == $date || null == $time) return null; $date->setTime($time->format('G'), $time->format('i')); return $date; } } 

The form display is correct, but when I submit the form, I get this error:

Note. A DateTime class object cannot be converted to int in /var/www/ttime/vendor/symfony/symfony/src/Symfony/Component/Form/Extension/Core/ChoiceList/ChoiceList.php line 457 500 Internal server error - ErrorException

While I have separated datetime elements + user selections correctly stored in DB.

I think the reverseTransform function returns a datetime format, and the form builder cannot convert it to a selection format:

array ('00: 00 '=> '00: 00', ...)

Can you tell me how to get rid of this error?

Is there a better way to do this?

+4
source share
1 answer

The array of data returned by the datatransformers data conversion function is an array of DateTime objects. These objects cannot be converted to select box values. To fix this, return the actual date and time string strings:

 $result = array( 'date' => $date->format('Ym-d'), 'time' => $time->format('H:i') ); 

Also, the reverseTransform function should then convert these strings back to the actual DateTime object using the following code:

 $dateTimeString = $array['date'] . ' ' . $array['time']; return DateTime::createFromFormat('Ymd H:i', $dateTimeString); 
+2
source

All Articles