4
votes

I'm trying to make custom datetime form fields. Like in this answer i have split datetime fields with one date form field and on time form field using a DataTransformer.

I use a jquery datepicker for date selection, but i want to have ONE custom choice form field for time selection whith half hours intervalls:

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

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

In my entity

/**
 * 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;
    }

...

}

The form type

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 the 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;
}
}

Form display is correct, but when i submit the form i get this error:

Notice: Object of class DateTime could not 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

Whereas i have the split items datetime + custom choice correctly persisted to DB.

I think that the reverseTransform function return datetime format, and the form builder can't convert it to the choice format:

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

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

Is there a better way for doing this?

1
Probably your entity or database where you are storing the date is defined as an INT. Why don't you copy them into your question?ButterDog
I've update the question, entity's objects are datetime objectsAlex

1 Answers

2
votes

The array of data returned by your datatransformers transform function is an array of DateTime objects. These objects can not be converted to choice-field values. To fix this return the actual formated date and time strings:

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

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

$dateTimeString = $array['date'] . ' ' . $array['time'];
return DateTime::createFromFormat('Y-m-d H:i', $dateTimeString);