feature #20496 [Form] Allow pass filter callback to delete_empty option. (Koc)
This PR was merged into the 3.4 branch.
Discussion
----------
[Form] Allow pass filter callback to delete_empty option.
| Q | A
| ------------- | ---
| Branch? | master
| Bug fix? | yes
| New feature? | yes
| BC breaks? | no
| Deprecations? | no
| Tests pass? | yes
| Fixed tickets | #13601, #13940, #22008, #22014
| License | MIT
| Doc PR | coming soon
Commits
-------
8630abe27a
[Form] Allow pass filter callback to delete_empty option.
This commit is contained in:
commit
c0d99d13c0
@ -48,7 +48,7 @@ class ResizeFormListener implements EventSubscriberInterface
|
||||
protected $allowDelete;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
* @var bool|callable
|
||||
*/
|
||||
private $deleteEmpty;
|
||||
|
||||
@ -148,14 +148,15 @@ class ResizeFormListener implements EventSubscriberInterface
|
||||
throw new UnexpectedTypeException($data, 'array or (\Traversable and \ArrayAccess)');
|
||||
}
|
||||
|
||||
if ($this->deleteEmpty) {
|
||||
$previousData = $event->getForm()->getData();
|
||||
if ($entryFilter = $this->deleteEmpty) {
|
||||
$previousData = $form->getData();
|
||||
foreach ($form as $name => $child) {
|
||||
$isNew = !isset($previousData[$name]);
|
||||
$isEmpty = is_callable($entryFilter) ? $entryFilter($child->getData()) : $child->isEmpty();
|
||||
|
||||
// $isNew can only be true if allowAdd is true, so we don't
|
||||
// need to check allowAdd again
|
||||
if ($child->isEmpty() && ($isNew || $this->allowDelete)) {
|
||||
if ($isEmpty && ($isNew || $this->allowDelete)) {
|
||||
unset($data[$name]);
|
||||
$form->remove($name);
|
||||
}
|
||||
|
@ -100,6 +100,7 @@ class CollectionType extends AbstractType
|
||||
));
|
||||
|
||||
$resolver->setNormalizer('entry_options', $entryOptionsNormalizer);
|
||||
$resolver->setAllowedTypes('delete_empty', array('bool', 'callable'));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -12,6 +12,7 @@
|
||||
namespace Symfony\Component\Form\Tests\Extension\Core\Type;
|
||||
|
||||
use Symfony\Component\Form\Tests\Fixtures\Author;
|
||||
use Symfony\Component\Form\Tests\Fixtures\AuthorType;
|
||||
|
||||
class CollectionTypeTest extends BaseTypeTest
|
||||
{
|
||||
@ -110,6 +111,49 @@ class CollectionTypeTest extends BaseTypeTest
|
||||
$this->assertEquals(array('foo@foo.com'), $form->getData());
|
||||
}
|
||||
|
||||
public function testResizedDownWithDeleteEmptyCallable()
|
||||
{
|
||||
$form = $this->factory->create(static::TESTED_TYPE, null, array(
|
||||
'entry_type' => AuthorType::class,
|
||||
'allow_delete' => true,
|
||||
'delete_empty' => function (Author $obj = null) {
|
||||
return null === $obj || empty($obj->firstName);
|
||||
},
|
||||
));
|
||||
|
||||
$form->setData(array(new Author('Bob'), new Author('Alice')));
|
||||
$form->submit(array(array('firstName' => 'Bob'), array('firstName' => '')));
|
||||
|
||||
$this->assertTrue($form->has('0'));
|
||||
$this->assertFalse($form->has('1'));
|
||||
$this->assertEquals(new Author('Bob'), $form[0]->getData());
|
||||
$this->assertEquals(array(new Author('Bob')), $form->getData());
|
||||
}
|
||||
|
||||
public function testResizedDownIfSubmittedWithCompoundEmptyDataDeleteEmptyAndNoDataClass()
|
||||
{
|
||||
$form = $this->factory->create(static::TESTED_TYPE, null, array(
|
||||
'entry_type' => AuthorType::class,
|
||||
// If the field is not required, no new Author will be created if the
|
||||
// form is completely empty
|
||||
'entry_options' => array('data_class' => null),
|
||||
'allow_add' => true,
|
||||
'allow_delete' => true,
|
||||
'delete_empty' => function ($author) {
|
||||
return empty($author['firstName']);
|
||||
},
|
||||
));
|
||||
$form->setData(array(array('firstName' => 'first', 'lastName' => 'last')));
|
||||
$form->submit(array(
|
||||
array('firstName' => 's_first', 'lastName' => 's_last'),
|
||||
array('firstName' => '', 'lastName' => ''),
|
||||
));
|
||||
$this->assertTrue($form->has('0'));
|
||||
$this->assertFalse($form->has('1'));
|
||||
$this->assertEquals(array('firstName' => 's_first', 'lastName' => 's_last'), $form[0]->getData());
|
||||
$this->assertEquals(array(array('firstName' => 's_first', 'lastName' => 's_last')), $form->getData());
|
||||
}
|
||||
|
||||
public function testDontAddEmptyDataIfDeleteEmpty()
|
||||
{
|
||||
$form = $this->factory->create(static::TESTED_TYPE, null, array(
|
||||
|
Reference in New Issue
Block a user