Browse Source

Merge remote branch 'kriswallsmith/form/collection-proto'

* kriswallsmith/form/collection-proto:
  added script[type="text/html"] collection prototype to form themes
  [Form] removed collection prototype from form tree
Fabien Potencier 14 năm trước cách đây
mục cha
commit
0c29a25d89

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

@@ -273,3 +273,12 @@
     {{ block('field_widget') }}
 {% endspaceless %}
 {% endblock email_widget %}
+
+{% block collection_widget %}
+{% spaceless %}
+    {{ block('form_widget') }}
+    {% if prototype %}
+    <script type="text/html" id="{{ id }}_prototype">{{ form_row(prototype) }}</script>
+    {% endif %}
+{% endspaceless %}
+{% endblock collection_widget %}

+ 5 - 0
src/Symfony/Bundle/FrameworkBundle/Resources/views/Form/collection_widget.html.php

@@ -0,0 +1,5 @@
+<?php $view->render('FrameworkBundle:Form:form_widget.html.php', array('form' => $form)) ?>
+
+<?php if (isset($prototype)): ?>
+<script type="text/html" id="<?php echo $view->escape($id) ?>_prototype"><?php echo $view['form']->row($prototype) ?></script>
+<?php endif; ?>

+ 4 - 6
src/Symfony/Component/Form/Extension/Core/EventListener/ResizeFormListener.php

@@ -83,11 +83,9 @@ class ResizeFormListener implements EventSubscriberInterface
             throw new UnexpectedTypeException($data, 'array or \Traversable');
         }
 
-        // First remove all rows except for the prototype row
+        // First remove all rows
         foreach ($form as $name => $child) {
-            if (!($this->allowAdd && '$$name$$' === $name)) {
-                $form->remove($name);
-            }
+            $form->remove($name);
         }
 
         // Then add all rows again in the correct order
@@ -111,10 +109,10 @@ class ResizeFormListener implements EventSubscriberInterface
             throw new UnexpectedTypeException($data, 'array or \Traversable');
         }
 
-        // Remove all empty rows except for the prototype row
+        // Remove all empty rows
         if ($this->allowDelete) {
             foreach ($form as $name => $child) {
-                if (!isset($data[$name]) && '$$name$$' !== $name) {
+                if (!isset($data[$name])) {
                     $form->remove($name);
                 }
             }

+ 6 - 4
src/Symfony/Component/Form/Extension/Core/Type/CollectionType.php

@@ -25,10 +25,8 @@ class CollectionType extends AbstractType
     public function buildForm(FormBuilder $builder, array $options)
     {
         if ($options['allow_add'] && $options['prototype']) {
-            $builder->add('$$name$$', $options['type'], array_replace(array(
-                'property_path' => false,
-                'required'      => false,
-            ), $options['options']));
+            $prototype = $builder->create('$$name$$', $options['type'], $options['options']);
+            $builder->setAttribute('prototype', $prototype->getForm());
         }
 
         $listener = new ResizeFormListener(
@@ -55,6 +53,10 @@ class CollectionType extends AbstractType
             ->set('allow_add', $form->getAttribute('allow_add'))
             ->set('allow_delete', $form->getAttribute('allow_delete'))
         ;
+
+        if ($form->hasAttribute('prototype')) {
+            $view->set('prototype', $form->getAttribute('prototype')->createView());
+        }
     }
 
     /**

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

@@ -1115,6 +1115,23 @@ abstract class AbstractLayoutTest extends \PHPUnit_Framework_TestCase
     [@type="url"]
     [@name="na&me"]
     [@value="http://www.google.com?foo1=bar1&foo2=bar2"]
+'
+        );
+    }
+
+    public function testCollectionPrototype()
+    {
+        $form = $this->factory->createNamedBuilder('form', 'na&me', array('items' => array('one', 'two', 'three')))
+            ->add('items', 'collection', array('allow_add' => true))
+            ->getForm()
+            ->createView();
+
+        $html = $this->renderWidget($form);
+
+        $this->assertMatchesXpath($html,
+'//script
+    [@id="na&me_items_prototype"]
+    [@type="text/html"]
 '
         );
     }

+ 0 - 24
tests/Symfony/Tests/Component/Form/Extension/Core/EventListener/ResizeFormListenerTest.php

@@ -67,30 +67,6 @@ class ResizeFormListenerTest extends \PHPUnit_Framework_TestCase
         $this->assertTrue($this->form->has('2'));
     }
 
-    public function testPreSetDataRemovesPrototypeRowIfNotAllowAdd()
-    {
-        $this->form->add($this->getForm('$$name$$'));
-
-        $data = array();
-        $event = new DataEvent($this->form, $data);
-        $listener = new ResizeFormListener($this->factory, 'text', array(), false, false);
-        $listener->preSetData($event);
-
-        $this->assertFalse($this->form->has('$$name$$'));
-    }
-
-    public function testPreSetDataDoesNotRemovePrototypeRowIfAllowAdd()
-    {
-        $this->form->add($this->getForm('$$name$$'));
-
-        $data = array();
-        $event = new DataEvent($this->form, $data);
-        $listener = new ResizeFormListener($this->factory, 'text', array(), true, false);
-        $listener->preSetData($event);
-
-        $this->assertTrue($this->form->has('$$name$$'));
-    }
-
     /**
      * @expectedException Symfony\Component\Form\Exception\UnexpectedTypeException
      */

+ 0 - 26
tests/Symfony/Tests/Component/Form/Extension/Core/Type/CollectionTypeTest.php

@@ -51,32 +51,6 @@ class CollectionFormTest extends TypeTestCase
         $this->assertEquals(20, $form[0]->getAttribute('max_length'));
     }
 
-    public function testSetDataAddsPrototypeIfAllowAdd()
-    {
-        $form = $this->factory->create('collection', null, array(
-            'type' => 'field',
-            'options' => array(
-                'max_length' => 20,
-            ),
-            'allow_add' => true,
-            'prototype' => true,
-        ));
-
-        $form->setData(array('foo@foo.com', 'foo@bar.com'));
-        $this->assertTrue($form[0] instanceof Form);
-        $this->assertTrue($form[1] instanceof Form);
-        $this->assertTrue($form['$$name$$'] instanceof Form);
-        $this->assertEquals(20, $form['$$name$$']->getAttribute('max_length'));
-        $this->assertEquals(3, count($form));
-
-        $form->setData(array('foo@baz.com'));
-        $this->assertTrue($form[0] instanceof Form);
-        $this->assertFalse(isset($form[1]));
-        $this->assertTrue($form['$$name$$'] instanceof Form);
-        $this->assertEquals(20, $form['$$name$$']->getAttribute('max_length'));
-        $this->assertEquals(2, count($form));
-    }
-
     public function testThrowsExceptionIfObjectIsNotTraversable()
     {
         $form = $this->factory->create('collection', null, array(