DataTransformer - 将DateTime分成两个字段(DataTransformer - split DateTime into two fields)

其他开发 IT屋
百度翻译此文   有道翻译此文
问 题

I recently build a DataTransformer that will accept a variety of different date formats in the end (like 12/12/2012 or 12.12.2012 or 2012-12-12).

My question is: before I had the date and time split up 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,
    ) )

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

Within my entity-type:

public function buildForm(FormBuilder $builder, array $options) {

    builder->add('date_end', 'dateTime', array(
        'label' => 'Date/Time',
        'required' => false,
    ) )
}

The corresponding DateTimeType I created:

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('Y-m-d H:i');
}

/**
 * @param  string $value
 * @return string|null
 */
public function reverseTransform($value)
{
    if ( (null === $value) || empty($value) ) {
        return null;
    }
    return new \DateTime( $value );

}
解决方案

I'm assuming you are using Symfony 2.0. I've read that form component has changed somewhat in 2.1.

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

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

My code looks similar to this (altered 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 it is a form (don't let it confuse you) but we will use it as a single logical field. That's where the data transformer comes in. It has to split a single DateTime instance into date and time to obtain data for the two subfields when displaying the form and vice-versa when the form is submitted.

The error_bubbling settings ensure that the errors generated by subfields attach to our new subfield and don't propagate to the top-level form, but you may have diferrent goal.

My data transformer 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 that:

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

You have to register it as a service to use it by alias, otherwise instantiate it directly (new MyDateTimeType()).

This may not be the prettiest solution but so is the form component in Symfony 2.0.

本文地址:IT屋 » DataTransformer - split DateTime into two fields

问 题

我最近建立了一个 DataTransformer ,它将最终接受各种不同的日期格式(如12/12/2012或12.12.2012或2012-12-12 )。



我的问题是:在将日期和时间分成两个不同的字段之前:

  $ 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,
))


哪些工作正常。我怎样才能用新的 DataTransformer ?



在我的实体类型中完成这项工作:



public function buildForm(FormBuilder $ builder,array $ options){

uilder-> (''date_end','dateTime',array(
'label'=>'Date / Time',
'required'=> false,
))
}


我创建的相应DateTimeType:



  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';




到目前为止我的变压器:



  / ** 
* @param \DateTime | null $ dateTime
* @return string | null
* /
public function transform($ dateTime){
if(null === $ dateTime){
return null;
}

返回$ dateTime->格式('Y-m-d H:i');

$ b / **
* @param string $ value
* @return string | null
* /
public function reverseTransform( $($ value)
{
if((null === $ value)|| empty($ value)){
return null;
}
返回新\DateTime($ value);



$ div $解析方案

假设你正在使用Symfony 2.0。我已经阅读过表单组件在2.1中有所变化。



我有一个类似的问题 - 我想要一个日期时间字段,使用日期和时间单独的小部件小时)输入。

首先,您必须为此字段创建单独的表单类型(实际上本身就是一种表单)。



我的代码看起来类似于这个(在这个例子中改变了):

  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'=>'选择',
'error_bubbling'=> true
));

$ builder-> appendClientTransformer(new DateTimeToDateTimeArrayTransformer());

$ b $ 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';






$ b

正如你所看到的,它是一种形式不要让它让你感到困惑),但我们会将它用作单一的逻辑领域。这就是数据转换器的作用。它必须将单个 DateTime 实例分割成日期和时间,以便在显示表单时获取两个子字段的数据,反之亦然表单被提交。

error_bubbling设置可确保子字段生成的错误附加到我们的新子字段,并且不会传播到顶级表单,但您可能拥有不同的目标。



我的数据转换器如下所示:

  class DateTimeToDateTimeArrayTransformer实现DataTransformerInterface 
{
public function transform($ datetime)
{
if(null!== $ datetime)
{
$ date = clone $日期时间;
$ date-> setTime(12,0,0);

$ time = clone $ datetime;
$ time-> setDate(1970,1,1);
}
else
{
$ date = null;
$ time = null;
}

$ result = array(
'date'=> $ date,
'time'=> $ time
);

返回$ 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;




最后你可以像这样使用它:



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


您必须将其注册为服务以别名使用它,否则直接实例化它()。



这可能不是最好的解决方案,但Symfony 2.0中的表单组件也是如此。 p>

本文地址:IT屋 » DataTransformer - 将DateTime分成两个字段

官方微信
扫一扫关注IT屋
微信公众号搜索 “ IT屋 ” ,选择关注
与百万开发者在一起