我最近构建了一个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) {
builder->add('date_end', 'dateTime', array(
'label' => 'Date/Time',
'required' => false,
) )
}
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;
}
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 );
}
答案 0 :(得分:2)
我假设你正在使用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' => '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';
}
}
正如您所看到的那样,它是一种形式(不要让它让您感到困惑),但我们会将其用作单个逻辑字段。这就是数据转换器的用武之地。它必须将单个DateTime
实例拆分为日期和时间,以便在显示表单时获取两个子字段的数据,反之亦然。
error_bubbling设置可确保子字段生成的错误附加到我们的新子字段,而不会传播到顶级表单,但您可能有不同的目标。
我的数据转换器如下所示:
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;
}
}
最后你可以这样使用它:
$builder->add('startDate', 'my_datetime', array(
'label' => 'label.form.date'
));
您必须register it as a service按别名使用它,否则直接将其实例化(new MyDateTimeType()
)。
这可能不是最漂亮的解决方案,但Symfony 2.0中的表单组件也是如此。