Skip to content

Commit

Permalink
Added to DateTimeType extension possibility to render form as `sing…
Browse files Browse the repository at this point in the history
…le_text` (similar to `DateType` option) (issue #1323 it requires fix for #1205)
  • Loading branch information
stloyd committed Jun 23, 2011
1 parent 17b41b2 commit 7bc19f9
Show file tree
Hide file tree
Showing 6 changed files with 149 additions and 83 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -71,12 +71,16 @@

{% block datetime_widget %}
{% spaceless %}
<div {{ block('widget_container_attributes') }}>
{{ form_errors(form.date) }}
{{ form_errors(form.time) }}
{{ form_widget(form.date) }}
{{ form_widget(form.time) }}
</div>
{% if widget == 'single_text' %}
{{ block('field_widget') }}
{% else %}
<div {{ block('widget_container_attributes') }}>
{{ form_errors(form.date) }}
{{ form_errors(form.time) }}
{{ form_widget(form.date) }}
{{ form_widget(form.time) }}
</div>
{% endif %}
{% endspaceless %}
{% endblock datetime_widget %}

Expand All @@ -99,7 +103,7 @@
{% block time_widget %}
{% spaceless %}
{% if widget == 'single_text' %}
{{ block('text_widget') }}
{{ block('field_widget') }}
{% else %}
<div {{ block('widget_container_attributes') }}>
{{ form_widget(form.hour, { 'attr': { 'size': '1' } }) }}:{{ form_widget(form.minute, { 'attr': { 'size': '1' } }) }}{% if with_seconds %}:{{ form_widget(form.second, { 'attr': { 'size': '1' } }) }}{% endif %}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
<div <?php echo $view['form']->renderBlock('container_attributes') ?>>
<?php echo $view['form']->widget($form['date'])
.' '
.$view['form']->widget($form['time']) ?>
</div>
<?php if ($widget == 'single_text'): ?>
<?php echo $view['form']->renderBlock('field_widget'); ?>
<?php else: ?>
<div <?php echo $view['form']->renderBlock('container_attributes') ?>>
<?php echo $view['form']->widget($form['date'])
. ' '
. $view['form']->widget($form['time']) ?>
</div>
<?php endif ?>
134 changes: 83 additions & 51 deletions src/Symfony/Component/Form/Extension/Core/Type/DateTimeType.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,9 @@
namespace Symfony\Component\Form\Extension\Core\Type;

use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormInterface;
use Symfony\Component\Form\FormBuilder;
use Symfony\Component\Form\FormView;
use Symfony\Component\Form\ReversedTransformer;
use Symfony\Component\Form\Extension\Core\DataTransformer\DataTransformerChain;
use Symfony\Component\Form\Extension\Core\DataTransformer\DateTimeToArrayTransformer;
Expand All @@ -27,38 +29,6 @@ class DateTimeType extends AbstractType
*/
public function buildForm(FormBuilder $builder, array $options)
{
// Only pass a subset of the options to children
$dateOptions = array_intersect_key($options, array_flip(array(
'years',
'months',
'days',
'empty_value',
'required',
)));
$timeOptions = array_intersect_key($options, array_flip(array(
'hours',
'minutes',
'seconds',
'with_seconds',
'empty_value',
'required',
)));

if (isset($options['date_widget'])) {
$dateOptions['widget'] = $options['date_widget'];
}
if (isset($options['date_format'])) {
$dateOptions['format'] = $options['date_format'];
}

$dateOptions['input'] = 'array';

if (isset($options['time_widget'])) {
$timeOptions['widget'] = $options['time_widget'];
}

$timeOptions['input'] = 'array';

$parts = array('year', 'month', 'day', 'hour', 'minute');
$timeParts = array('hour', 'minute');

Expand All @@ -67,17 +37,54 @@ public function buildForm(FormBuilder $builder, array $options)
$timeParts[] = 'second';
}

$builder
->appendClientTransformer(new DataTransformerChain(array(
new DateTimeToArrayTransformer($options['data_timezone'], $options['user_timezone'], $parts),
new ArrayToPartsTransformer(array(
'date' => array('year', 'month', 'day'),
'time' => $timeParts,
)),
)))
->add('date', 'date', $dateOptions)
->add('time', 'time', $timeOptions)
;
// If `widget` is set to `single_text`, ignore widget options from `date` and `time`
if ($options['widget'] === 'single_text') {
$builder->appendClientTransformer(new DateTimeToStringTransformer($options['data_timezone'], $options['user_timezone'], 'Y-m-d H:i:s'));
} else {
// Only pass a subset of the options to children
$dateOptions = array_intersect_key($options, array_flip(array(
'years',
'months',
'days',
'empty_value',
'required',
)));
$timeOptions = array_intersect_key($options, array_flip(array(
'hours',
'minutes',
'seconds',
'with_seconds',
'empty_value',
'required',
)));

if (isset($options['date_widget'])) {
$dateOptions['widget'] = $options['date_widget'];
}
if (isset($options['date_format'])) {
$dateOptions['format'] = $options['date_format'];
}

$dateOptions['input'] = 'array';

if (isset($options['time_widget'])) {
$timeOptions['widget'] = $options['time_widget'];
}

$timeOptions['input'] = 'array';

$builder
->appendClientTransformer(new DataTransformerChain(array(
new DateTimeToArrayTransformer($options['data_timezone'], $options['user_timezone'], $parts),
new ArrayToPartsTransformer(array(
'date' => array('year', 'month', 'day'),
'time' => $timeParts,
)),
)))
->add('date', 'date', $dateOptions)
->add('time', 'time', $timeOptions)
;
}

if ($options['input'] === 'string') {
$builder->appendNormTransformer(new ReversedTransformer(
Expand All @@ -92,6 +99,16 @@ public function buildForm(FormBuilder $builder, array $options)
new DateTimeToArrayTransformer($options['data_timezone'], $options['data_timezone'], $parts)
));
}

$builder->setAttribute('widget', $options['widget']);
}

/**
* {@inheritdoc}
*/
public function buildView(FormView $view, FormInterface $form)
{
$view->set('widget', $form->getAttribute('widget'));
}

/**
Expand All @@ -101,12 +118,10 @@ public function getDefaultOptions(array $options)
{
return array(
'input' => 'datetime',
// This will overwrite "widget" child options
'widget' => null,
'data_timezone' => null,
'user_timezone' => null,
'empty_value' => null,
// Don't modify \DateTime classes by reference, we treat
// them like immutable value objects
'by_reference' => false,
'date_widget' => null,
'date_format' => null,
'time_widget' => null,
Expand All @@ -119,6 +134,9 @@ public function getDefaultOptions(array $options)
'minutes' => range(0, 59),
'seconds' => range(0, 59),
'with_seconds' => false,
// Don't modify \DateTime classes by reference, we treat
// them like immutable value objects
'by_reference' => false,
);
}

Expand All @@ -128,34 +146,48 @@ public function getDefaultOptions(array $options)
public function getAllowedOptionValues(array $options)
{
return array(
'input' => array(
'input' => array(
'datetime',
'string',
'timestamp',
'array',
),
'date_widget' => array(
'date_widget' => array(
null, // inherit default from DateType
'single_text',
'text',
'choice',
),
'date_format' => array(
'date_format' => array(
null, // inherit default from DateType
\IntlDateFormatter::FULL,
\IntlDateFormatter::LONG,
\IntlDateFormatter::MEDIUM,
\IntlDateFormatter::SHORT,
),
'time_widget' => array(
'time_widget' => array(
null, // inherit default from TimeType
'single_text',
'text',
'choice',
),
// This option will overwrite "date_widget" and "time_widget" options
'widget' => array(
'single_text',
'text',
'choice',
),
);
}

/**
* {@inheritdoc}
*/
public function getParent(array $options)
{
return $options['widget'] === 'single_text' ? 'field' : 'form';
}

/**
* {@inheritdoc}
*/
Expand Down
6 changes: 4 additions & 2 deletions src/Symfony/Component/Form/Extension/Core/Type/TimeType.php
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,8 @@ public function buildForm(FormBuilder $builder, array $options)
if ($options['widget'] === 'single_text') {
$builder->appendClientTransformer(new DateTimeToStringTransformer($options['data_timezone'], $options['user_timezone'], 'H:i:s'));
} else if ($options['widget'] === 'choice') {
if (is_array($options['empty_value'])) { $options['empty_value'] = array_merge(array('hour' => null, 'minute' => null, 'second' => null), $options['empty_value']);
if (is_array($options['empty_value'])) {
$options['empty_value'] = array_merge(array('hour' => null, 'minute' => null, 'second' => null), $options['empty_value']);
} else {
$options['empty_value'] = array('hour' => $options['empty_value'], 'minute' => $options['empty_value'], 'second' => $options['empty_value']);
}
Expand Down Expand Up @@ -65,9 +66,10 @@ public function buildForm(FormBuilder $builder, array $options)
}

$parts = array('hour', 'minute');
if ($options['with_seconds']) { if ($options['with_seconds']) {
if ($options['with_seconds']) {
$parts[] = 'second';
}

if ($options['input'] === 'string') {
$builder->appendNormTransformer(new ReversedTransformer(
new DateTimeToStringTransformer($options['data_timezone'], $options['data_timezone'], 'H:i:s')
Expand Down
45 changes: 27 additions & 18 deletions tests/Symfony/Tests/Component/Form/AbstractLayoutTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -810,6 +810,7 @@ public function testDateTimeWithEmptyValueGlobal()
'
);
}

public function testDateTimeWithEmptyValueOnTime()
{
$form = $this->factory->createNamed('datetime', 'na&me', '2011-02-03', array(
Expand Down Expand Up @@ -913,38 +914,46 @@ public function testDateTimeSingleText()
[@value="Feb 3, 2011"]
/following-sibling::input
[@type="text"]
[@name="na&me[time]"]
[@id="na&me_time"]
[@name="na&me[time]"]
[@value="04:05:00"]
]
'
);
}

public function testDateTimeWithSecondsSingleText()
public function testDateTimeWithWidgetSingleText()
{
$form = $this->factory->createNamed('datetime', 'name', '2011-02-03 04:05:06', array(
'property_path' => 'name',
'input' => 'string',
'date_widget' => 'single_text',
'time_widget' => 'single_text',
'with_seconds' => true,
'widget' => 'single_text',
));

$this->assertWidgetMatchesXpath($form->createView(), array(),
'/div
[
./input
[@type="text"]
[@id="name_date"]
[@name="name[date]"]
[@value="Feb 3, 2011"]
/following-sibling::input
[@type="text"]
[@name="name[time]"]
[@id="name_time"]
[@value="04:05:06"]
]
'/input
[@type="text"]
[@name="name"]
[@value="2011-02-03 04:05:06"]
'
);
}

public function testDateTimeWithWidgetSingleTextIgnoreDateAndTimeWidgets()
{
$form = $this->factory->createNamed('datetime', 'na&me', '2011-02-03 04:05:06', array(
'property_path' => 'name',
'input' => 'string',
'date_widget' => 'choice',
'time_widget' => 'choice',
'widget' => 'single_text',
));

$this->assertWidgetMatchesXpath($form->createView(), array(),
'/input
[@type="text"]
[@name="na&me"]
[@value="2011-02-03 04:05:06"]
'
);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -160,4 +160,19 @@ public function testSubmit_differentTimezones()

$this->assertEquals($dateTime->format('Y-m-d H:i:s'), $form->getData());
}

public function testSubmit_stringSingleText()
{
$form = $this->factory->create('datetime', null, array(
'data_timezone' => 'UTC',
'user_timezone' => 'UTC',
'input' => 'string',
'widget' => 'single_text',
));

$form->bind('2010-06-02 03:04:00');

$this->assertEquals('2010-06-02 03:04:00', $form->getData());
$this->assertEquals('2010-06-02 03:04:00', $form->getClientData());
}
}

0 comments on commit 7bc19f9

Please sign in to comment.