[Form] Add support for sorting fields
This commit is contained in:
parent
bb1e1e58ae
commit
62650bbdc7
@ -15,6 +15,7 @@ CHANGELOG
|
||||
* Added a `choice_translation_parameters` option to `ChoiceType`
|
||||
* Add `UuidType` and `UlidType`
|
||||
* Dependency on `symfony/intl` was removed. Install `symfony/intl` if you are using `LocaleType`, `CountryType`, `CurrencyType`, `LanguageType` or `TimezoneType`.
|
||||
* Add `priority` option to `BaseType` and sorting view fields
|
||||
|
||||
5.2.0
|
||||
-----
|
||||
|
@ -107,6 +107,7 @@ abstract class BaseType extends AbstractType
|
||||
'translation_domain' => $translationDomain,
|
||||
'label_translation_parameters' => $labelTranslationParameters,
|
||||
'attr_translation_parameters' => $attrTranslationParameters,
|
||||
'priority' => $options['priority'],
|
||||
// Using the block name here speeds up performance in collection
|
||||
// forms, where each entry has the same full block name.
|
||||
// Including the type is important too, because if rows of a
|
||||
@ -135,11 +136,15 @@ abstract class BaseType extends AbstractType
|
||||
'attr' => [],
|
||||
'translation_domain' => null,
|
||||
'auto_initialize' => true,
|
||||
'priority' => 0,
|
||||
]);
|
||||
|
||||
$resolver->setAllowedTypes('block_prefix', ['null', 'string']);
|
||||
$resolver->setAllowedTypes('attr', 'array');
|
||||
$resolver->setAllowedTypes('row_attr', 'array');
|
||||
$resolver->setAllowedTypes('label_html', 'bool');
|
||||
$resolver->setAllowedTypes('priority', 'int');
|
||||
|
||||
$resolver->setInfo('priority', 'The form rendering priority (higher priorities will be rendered first)');
|
||||
}
|
||||
}
|
||||
|
@ -1044,11 +1044,38 @@ class Form implements \IteratorAggregate, FormInterface, ClearableErrorsInterfac
|
||||
$view->children[$name] = $child->createView($view);
|
||||
}
|
||||
|
||||
$this->sort($view->children);
|
||||
|
||||
$type->finishView($view, $this, $options);
|
||||
|
||||
return $view;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sorts view fields based on their priority value.
|
||||
*/
|
||||
private function sort(array &$children): void
|
||||
{
|
||||
$c = [];
|
||||
$i = 0;
|
||||
$needsSorting = false;
|
||||
foreach ($children as $name => $child) {
|
||||
$c[$name] = ['p' => $child->vars['priority'] ?? 0, 'i' => $i++];
|
||||
|
||||
if (0 !== $c[$name]['p']) {
|
||||
$needsSorting = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!$needsSorting) {
|
||||
return;
|
||||
}
|
||||
|
||||
uksort($children, static function ($a, $b) use ($c): int {
|
||||
return [$c[$b]['p'], $c[$a]['i']] <=> [$c[$a]['p'], $c[$b]['i']];
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Normalizes the underlying data if a model transformer is set.
|
||||
*
|
||||
|
@ -836,6 +836,29 @@ class FormTypeTest extends BaseTypeTest
|
||||
$this->assertSame($view->vars['id'], $view['child1']->vars['attr']['form']);
|
||||
$this->assertSame($view->vars['id'], $view['child2']->vars['attr']['form']);
|
||||
}
|
||||
|
||||
public function testSortingViewChildrenBasedOnPriorityOption()
|
||||
{
|
||||
$view = $this->factory->createNamedBuilder('parent', self::TESTED_TYPE)
|
||||
->add('child1', null, ['priority' => -1])
|
||||
->add('child2')
|
||||
->add('child3', null, ['priority' => -1])
|
||||
->add('child4')
|
||||
->add('child5', null, ['priority' => 1])
|
||||
->add('child6')
|
||||
->getForm()
|
||||
->createView();
|
||||
|
||||
$expected = [
|
||||
'child5',
|
||||
'child2',
|
||||
'child4',
|
||||
'child6',
|
||||
'child1',
|
||||
'child3',
|
||||
];
|
||||
$this->assertSame($expected, array_keys($view->children));
|
||||
}
|
||||
}
|
||||
|
||||
class Money
|
||||
|
@ -57,6 +57,7 @@
|
||||
"mapped",
|
||||
"method",
|
||||
"post_max_size_message",
|
||||
"priority",
|
||||
"property_path",
|
||||
"required",
|
||||
"row_attr",
|
||||
|
@ -34,6 +34,7 @@ Symfony\Component\Form\Extension\Core\Type\ChoiceType (Block prefix: "choice")
|
||||
mapped
|
||||
method
|
||||
post_max_size_message
|
||||
priority
|
||||
property_path
|
||||
required
|
||||
row_attr
|
||||
|
@ -35,6 +35,7 @@
|
||||
"mapped",
|
||||
"method",
|
||||
"post_max_size_message",
|
||||
"priority",
|
||||
"property_path",
|
||||
"required",
|
||||
"row_attr",
|
||||
|
@ -37,6 +37,7 @@ Symfony\Component\Form\Extension\Core\Type\FormType (Block prefix: "form")
|
||||
mapped
|
||||
method
|
||||
post_max_size_message
|
||||
priority
|
||||
property_path
|
||||
required
|
||||
row_attr
|
||||
|
Reference in New Issue
Block a user