From 62650bbdc7949798550f644531ddab4b8d8526ea Mon Sep 17 00:00:00 2001 From: Yonel Ceruto Date: Fri, 2 Apr 2021 09:52:16 -0400 Subject: [PATCH] [Form] Add support for sorting fields --- src/Symfony/Component/Form/CHANGELOG.md | 1 + .../Form/Extension/Core/Type/BaseType.php | 5 ++++ src/Symfony/Component/Form/Form.php | 27 +++++++++++++++++++ .../Extension/Core/Type/FormTypeTest.php | 23 ++++++++++++++++ .../Descriptor/resolved_form_type_1.json | 1 + .../Descriptor/resolved_form_type_1.txt | 1 + .../Descriptor/resolved_form_type_2.json | 1 + .../Descriptor/resolved_form_type_2.txt | 1 + 8 files changed, 60 insertions(+) diff --git a/src/Symfony/Component/Form/CHANGELOG.md b/src/Symfony/Component/Form/CHANGELOG.md index 2ab805eb990b1..9a8dae4739d53 100644 --- a/src/Symfony/Component/Form/CHANGELOG.md +++ b/src/Symfony/Component/Form/CHANGELOG.md @@ -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 ----- diff --git a/src/Symfony/Component/Form/Extension/Core/Type/BaseType.php b/src/Symfony/Component/Form/Extension/Core/Type/BaseType.php index 3b5a3a01b5601..4ac58bd2acd05 100644 --- a/src/Symfony/Component/Form/Extension/Core/Type/BaseType.php +++ b/src/Symfony/Component/Form/Extension/Core/Type/BaseType.php @@ -107,6 +107,7 @@ public function buildView(FormView $view, FormInterface $form, array $options) '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 @@ public function configureOptions(OptionsResolver $resolver) '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)'); } } diff --git a/src/Symfony/Component/Form/Form.php b/src/Symfony/Component/Form/Form.php index e22415c95efdb..1901524562c6a 100644 --- a/src/Symfony/Component/Form/Form.php +++ b/src/Symfony/Component/Form/Form.php @@ -1044,11 +1044,38 @@ public function createView(FormView $parent = null) $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. * diff --git a/src/Symfony/Component/Form/Tests/Extension/Core/Type/FormTypeTest.php b/src/Symfony/Component/Form/Tests/Extension/Core/Type/FormTypeTest.php index ffbcfbaa64f15..3701b653f855e 100644 --- a/src/Symfony/Component/Form/Tests/Extension/Core/Type/FormTypeTest.php +++ b/src/Symfony/Component/Form/Tests/Extension/Core/Type/FormTypeTest.php @@ -836,6 +836,29 @@ public function testFormAttrAsStringWithNoId() $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 diff --git a/src/Symfony/Component/Form/Tests/Fixtures/Descriptor/resolved_form_type_1.json b/src/Symfony/Component/Form/Tests/Fixtures/Descriptor/resolved_form_type_1.json index 2b51a6e40b131..c9f453c8d6cc6 100644 --- a/src/Symfony/Component/Form/Tests/Fixtures/Descriptor/resolved_form_type_1.json +++ b/src/Symfony/Component/Form/Tests/Fixtures/Descriptor/resolved_form_type_1.json @@ -57,6 +57,7 @@ "mapped", "method", "post_max_size_message", + "priority", "property_path", "required", "row_attr", diff --git a/src/Symfony/Component/Form/Tests/Fixtures/Descriptor/resolved_form_type_1.txt b/src/Symfony/Component/Form/Tests/Fixtures/Descriptor/resolved_form_type_1.txt index 42e858528e565..c4c4e901804af 100644 --- a/src/Symfony/Component/Form/Tests/Fixtures/Descriptor/resolved_form_type_1.txt +++ b/src/Symfony/Component/Form/Tests/Fixtures/Descriptor/resolved_form_type_1.txt @@ -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 diff --git a/src/Symfony/Component/Form/Tests/Fixtures/Descriptor/resolved_form_type_2.json b/src/Symfony/Component/Form/Tests/Fixtures/Descriptor/resolved_form_type_2.json index 5bb64c00fd5ab..225ec9ae08600 100644 --- a/src/Symfony/Component/Form/Tests/Fixtures/Descriptor/resolved_form_type_2.json +++ b/src/Symfony/Component/Form/Tests/Fixtures/Descriptor/resolved_form_type_2.json @@ -35,6 +35,7 @@ "mapped", "method", "post_max_size_message", + "priority", "property_path", "required", "row_attr", diff --git a/src/Symfony/Component/Form/Tests/Fixtures/Descriptor/resolved_form_type_2.txt b/src/Symfony/Component/Form/Tests/Fixtures/Descriptor/resolved_form_type_2.txt index 30ba52c92a3a5..40506a1f67a1d 100644 --- a/src/Symfony/Component/Form/Tests/Fixtures/Descriptor/resolved_form_type_2.txt +++ b/src/Symfony/Component/Form/Tests/Fixtures/Descriptor/resolved_form_type_2.txt @@ -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 pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy