Browse Source

Added to `TimeType` extension possibility to render form as `single_text` (similar to DateType option) (issue #1205)
Adjusted `DateTimeType` to allow usage of this new feature

stloyd 14 năm trước cách đây
mục cha
commit
ad5d2c13e1

+ 7 - 3
src/Symfony/Bridge/Twig/Resources/views/Form/form_div_layout.html.twig

@@ -98,9 +98,13 @@
 
 {% block time_widget %}
 {% spaceless %}
-    <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 %}
-    </div>
+    {% if widget == 'single_text' %}
+        {{ block('text_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 %}
+        </div>
+    {% endif %}
 {% endspaceless %}
 {% endblock time_widget %}
 

+ 24 - 13
src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/time_widget.html.php

@@ -1,14 +1,25 @@
-<div <?php echo $view['form']->renderBlock('container_attributes') ?>>
-    <?php
-        // There should be no spaces between the colons and the widgets, that's why
-        // this block is written in a single PHP tag
-        echo $view['form']->widget($form['hour'], array('attr' => array('size' => 1)));
-        echo ':';
-        echo $view['form']->widget($form['minute'], array('attr' => array('size' => 1)));
-
-        if ($with_seconds) {
+<?php if ($widget == 'single_text'): ?>
+    <input type="text"
+        <?php echo $view['form']->renderBlock('attributes') ?>
+        name="<?php echo $view->escape($full_name) ?>"
+        value="<?php echo $view->escape($value) ?>"
+        <?php if ($read_only): ?>disabled="disabled"<?php endif ?>
+        <?php if ($required): ?>required="required"<?php endif ?>
+        <?php if ($max_length): ?>maxlength="<?php echo $max_length ?>"<?php endif ?>
+    />
+<?php else: ?>
+    <div<?php echo $view['form']->renderBlock('container_attributes') ?>>
+        <?php
+            // There should be no spaces between the colons and the widgets, that's why
+            // this block is written in a single PHP tag
+            echo $view['form']->widget($form['hour'], array('attr' => array('size' => 1)));
             echo ':';
-            echo $view['form']->widget($form['second'], array('attr' => array('size' => 1)));
-        }
-    ?>
-</div>
+            echo $view['form']->widget($form['minute'], array('attr' => array('size' => 1)));
+
+            if ($with_seconds) {
+                echo ':';
+                echo $view['form']->widget($form['second'], array('attr' => array('size' => 1)));
+            }
+        ?>
+    </div>
+<?php endif ?>

+ 1 - 0
src/Symfony/Component/Form/Extension/Core/Type/DateTimeType.php

@@ -149,6 +149,7 @@ class DateTimeType extends AbstractType
              ),
             'time_widget'   => array(
                 null, // inherit default from TimeType
+                'single_text',
                 'text',
                 'choice',
             ),

+ 23 - 11
src/Symfony/Component/Form/Extension/Core/Type/TimeType.php

@@ -28,7 +28,14 @@ class TimeType extends AbstractType
      */
     public function buildForm(FormBuilder $builder, array $options)
     {
-        if ($options['widget'] === 'choice') {
+        $parts = array('hour', 'minute');
+        if ($options['with_seconds']) {
+            $parts[] = 'second';
+        }
+
+        if ($options['widget'] === 'single_text') {
+            $builder->appendClientTransformer(new DateTimeToStringTransformer($options['data_timezone'], $options['user_timezone'], 'H:i:s'));
+        } else {
             if (is_array($options['empty_value'])) {
                 $options['empty_value'] = array_merge(array('hour' => null, 'minute' => null, 'second' => null), $options['empty_value']);
             } else {
@@ -61,11 +68,13 @@ class TimeType extends AbstractType
                     'required' => $options['required'],
                 ));
             }
-        }
 
-        $parts = array('hour', 'minute');
-        if ($options['with_seconds']) {
-            $parts[] = 'second';
+            $builder->appendClientTransformer(new DateTimeToArrayTransformer(
+                $options['data_timezone'],
+                $options['user_timezone'],
+                $parts,
+                $options['widget'] === 'text'
+            ));
         }
 
         if ($options['input'] === 'string') {
@@ -83,12 +92,6 @@ class TimeType extends AbstractType
         }
 
         $builder
-            ->appendClientTransformer(new DateTimeToArrayTransformer(
-                $options['data_timezone'],
-                $options['user_timezone'],
-                $parts,
-                $options['widget'] === 'text'
-            ))
             ->setAttribute('widget', $options['widget'])
             ->setAttribute('with_seconds', $options['with_seconds'])
         ;
@@ -139,12 +142,21 @@ class TimeType extends AbstractType
                 'array',
             ),
             'widget' => array(
+                'single_text',
                 'text',
                 'choice',
             ),
         );
     }
 
+    /**
+     * {@inheritdoc}
+     */
+    public function getParent(array $options)
+    {
+        return $options['widget'] === 'single_text' ? 'field' : 'form';
+    }
+
     /**
      * {@inheritdoc}
      */

+ 56 - 1
tests/Symfony/Tests/Component/Form/AbstractLayoutTest.php

@@ -894,6 +894,61 @@ abstract class AbstractLayoutTest extends \PHPUnit_Framework_TestCase
         );
     }
 
+    public function testDateTimeSingleText()
+    {
+        $form = $this->factory->createNamed('datetime', 'na&me', '2011-02-03 04:05:06', array(
+            'property_path' => 'name',
+            'input' => 'string',
+            'date_widget' => 'single_text',
+            'time_widget' => 'single_text',
+        ));
+
+        $this->assertWidgetMatchesXpath($form->createView(), array(),
+'/div
+    [
+        ./input
+            [@type="text"]
+            [@id="na&me_date"]
+            [@name="na&me[date]"]
+            [@value="Feb 3, 2011"]
+        /following-sibling::input
+            [@type="text"]
+            [@name="na&me[time]"]
+            [@id="na&me_time"]
+            [@value="04:05:00"]
+    ]
+'
+        );
+    }
+
+    public function testDateTimeWithSecondsSingleText()
+    {
+        $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,
+        ));
+
+        $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"]
+    ]
+'
+        );
+    }
+
     public function testDateChoice()
     {
         $form = $this->factory->createNamed('date', 'na&me', '2011-02-03', array(
@@ -1448,7 +1503,7 @@ abstract class AbstractLayoutTest extends \PHPUnit_Framework_TestCase
         );
     }
 
-    public function testTimeWithEmptyValueGlobal()
+    public function testTimeSingleText()    {        $form = $this->factory->createNamed('time', 'na&me', '04:05:06', array(            'property_path' => 'name',            'input' => 'string',            'widget' => 'single_text',        ));        $this->assertWidgetMatchesXpath($form->createView(), array(),'/input    [@type="text"]    [@name="na&me"]    [@value="04:05:06"]    [@id="my&id"]    [@class="my&class"]'        );    }    public function testTimeWithEmptyValueGlobal()
     {
         $form = $this->factory->createNamed('time', 'na&me', null, array(
             'property_path' => 'name',

+ 74 - 0
tests/Symfony/Tests/Component/Form/Extension/Core/Type/TimeTypeTest.php

@@ -102,6 +102,80 @@ class TimeTypeTest extends LocalizedTestCase
         $this->assertEquals($input, $form->getClientData());
     }
 
+    public function testSubmit_arraySingleText()
+    {
+        $form = $this->factory->create('time', null, array(
+            'data_timezone' => 'UTC',
+            'user_timezone' => 'UTC',
+            'input' => 'array',
+            'widget' => 'single_text',
+        ));
+
+        $data = array(
+            'hour' => '3',
+            'minute' => '4',
+        );
+
+        $form->bind('03:04');
+
+        $this->assertEquals($data, $form->getData());
+        $this->assertEquals('03:04:00', $form->getClientData());
+    }
+
+    public function testSubmit_arraySingleTextWithSeconds()
+    {
+        $form = $this->factory->create('time', null, array(
+            'data_timezone' => 'UTC',
+            'user_timezone' => 'UTC',
+            'input' => 'array',
+            'widget' => 'single_text',
+            'with_seconds' => true,
+        ));
+
+        $data = array(
+            'hour' => '3',
+            'minute' => '4',
+            'second' => '5',
+        );
+
+        $form->bind('03:04:05');
+
+        $this->assertEquals($data, $form->getData());
+        $this->assertEquals('03:04:05', $form->getClientData());
+    }
+
+    public function testSubmit_datetimeSingleText()
+    {
+        $form = $this->factory->create('time', null, array(
+            'data_timezone' => 'UTC',
+            'user_timezone' => 'UTC',
+            'input' => 'datetime',
+            'widget' => 'single_text',
+        ));
+
+        $form->bind('03:04:05');
+
+        $this->assertEquals(new \DateTime('03:04:05 UTC'), $form->getData());
+        $this->assertEquals('03:04:05', $form->getClientData());
+    }
+
+    public function testSubmit_stringSingleText()
+    {
+        $form = $this->factory->create('time', null, array(
+            'data_timezone' => 'UTC',
+            'user_timezone' => 'UTC',
+            'input' => 'string',
+            'widget' => 'single_text',
+        ));
+
+        $time = '03:04:05';
+
+        $form->bind($time);
+
+        $this->assertEquals($time, $form->getData());
+        $this->assertEquals($time, $form->getClientData());
+    }
+
     public function testSetData_withSeconds()
     {
         $form = $this->factory->create('time', null, array(