Bläddra i källkod

[Form] allowed an empty value to be displayed for choices even when required is true

Rules are as follows:

* If multiple is true, then the empty_value is ignored
* If not, and if the field is not required, the empty_value is set to the empty string by default and displayed
* If the field is required, and if the user explicitely set the empty_value, then it is displayed
Fabien Potencier 14 år sedan
förälder
incheckning
c364008a3b

+ 1 - 1
src/Symfony/Bridge/Twig/Resources/views/Form/div_layout.html.twig

@@ -133,7 +133,7 @@
         </div>
     {% else %}
     <select {{ block('attributes') }}{% if multiple %} multiple="multiple"{% endif %}>
-        {% if not multiple and not required %}
+        {% if not multiple and empty_value is not none %}
             <option value="">{{ empty_value }}</option>
         {% endif %}
         {% if preferred_choices|length > 0 %}

+ 1 - 1
src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/choice_widget.html.php

@@ -12,7 +12,7 @@
         <?php if ($read_only): ?> disabled="disabled"<?php endif ?>
         <?php if ($multiple): ?> multiple="multiple"<?php endif ?>
     >
-        <?php if (!$multiple && !$required): ?><option value=""><?php echo $empty_value; ?></option><?php endif; ?>
+        <?php if (!$multiple && null !== $empty_value): ?><option value=""><?php echo $empty_value; ?></option><?php endif; ?>
         <?php if (count($preferred_choices) > 0): ?>
             <?php foreach ($preferred_choices as $choice => $label): ?>
                 <?php if ($view['form']->isChoiceGroup($label)): ?>

+ 2 - 1
src/Symfony/Component/Form/Extension/Core/Type/ChoiceType.php

@@ -70,6 +70,7 @@ class ChoiceType extends AbstractType
             ->setAttribute('preferred_choices', $options['preferred_choices'])
             ->setAttribute('multiple', $options['multiple'])
             ->setAttribute('expanded', $options['expanded'])
+            ->setAttribute('required', $options['required'])
         ;
 
         if ($options['expanded']) {
@@ -105,7 +106,7 @@ class ChoiceType extends AbstractType
             ->set('preferred_choices', array_intersect_key($choices, $preferred))
             ->set('choices', array_diff_key($choices, $preferred))
             ->set('separator', '-------------------')
-            ->set('empty_value', '')
+            ->set('empty_value', !$form->getAttribute('multiple') && !$form->getAttribute('required') ? '' : null)
         ;
 
         if ($view->get('multiple') && !$view->get('expanded')) {

+ 23 - 0
tests/Symfony/Tests/Component/Form/AbstractLayoutTest.php

@@ -380,6 +380,29 @@ abstract class AbstractLayoutTest extends \PHPUnit_Framework_TestCase
         );
     }
 
+    public function testSingleChoiceRequiredWithEmptyValue()
+    {
+        $form = $this->factory->createNamed('choice', 'na&me', '&a', array(
+            'property_path' => 'name',
+            'choices' => array('&a' => 'Choice&A', '&b' => 'Choice&B'),
+            'required' => true,
+            'multiple' => false,
+            'expanded' => false,
+        ));
+
+        $this->assertWidgetMatchesXpath($form->createView(), array('empty_value' => ''),
+'/select
+    [@name="na&me"]
+    [
+        ./option[@value=""][.=""]
+        /following-sibling::option[@value="&a"][@selected="selected"][.="Choice&A"]
+        /following-sibling::option[@value="&b"][not(@selected)][.="Choice&B"]
+    ]
+    [count(./option)=3]
+'
+        );
+    }
+
     public function testSingleChoiceGrouped()
     {
         $form = $this->factory->createNamed('choice', 'na&me', '&a', array(