8000 [Form] Add support for sorting fields · symfony/symfony@62650bb · GitHub
[go: up one dir, main page]

Skip to content

Commit 62650bb

Browse files
ycerutoNyholm
authored andcommitted
[Form] Add support for sorting fields
1 parent bb1e1e5 commit 62650bb

File tree

8 files changed

+60
-0
lines changed

8 files changed

+60
-0
lines changed

src/Symfony/Component/Form/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ CHANGELOG
1515
* Added a `choice_translation_parameters` option to `ChoiceType`
1616
* Add `UuidType` and `UlidType`
1717
* Dependency on `symfony/intl` was removed. Install `symfony/intl` if you are using `LocaleType`, `CountryType`, `CurrencyType`, `LanguageType` or `TimezoneType`.
18+
* Add `priority` option to `BaseType` and sorting view fields
1819

1920
5.2.0
2021
-----

src/Symfony/Component/Form/Extension/Core/Type/BaseType.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,7 @@ public function buildView(FormView $view, FormInterface $form, array $options)
107107
'translation_domain' => $translationDomain,
108108
'label_translation_parameters' => $labelTranslationParameters,
109109
'attr_translation_parameters' => $attrTranslationParameters,
110+
'priority' => $options['priority'],
110111
// Using the block name here speeds up performance in collection
111112
// forms, where each entry has the same full block name.
112113
// Including the type is important too, because if rows of a
@@ -135,11 +136,15 @@ public function configureOptions(OptionsResolver $resolver)
135136
'attr' => [],
136137
'translation_domain' => null,
137138
'auto_initialize' => true,
139+
'priority' => 0,
138140
]);
139141

140142
$resolver->setAllowedTypes('block_prefix', ['null', 'string']);
141143
$resolver->setAllowedTypes('attr', 'array');
142144
$resolver->setAllowedTypes('row_attr', 'array');
143145
$resolver->setAllowedTypes('label_html', 'bool');
146+
$resolver->setAllowedTypes('priority', 'int');
147+
148+
$resolver->setInfo('priority', 'The form rendering priority (higher priorities will be rendered first)');
144149
}
145150
}

src/Symfony/Component/Form/Form.php

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1044,11 +1044,38 @@ public function createView(FormView $parent = null)
10441044
$view->children[$name] = $child->createView($view);
10451045
}
10461046

1047+
$this->sort($view->children);
1048+
10471049
$type->finishView($view, $this, $options);
10481050

10491051
return $view;
10501052
}
10511053

1054+
/**
1055+
* Sorts view fields based on their priority value.
1056+
*/
1057+
private function sort(array &$children): void
1058+
{
1059+
$c = [];
1060+
$i = 0;
1061+
$needsSorting = false;
1062+
foreach ($children as $name => $child) {
1063+
$c[$name] = ['p' => $child->vars['priority'] ?? 0, 'i' => $i++];
1064+
1065+
if (0 !== $c[$name]['p']) {
1066+
$needsSorting = true;
1067+
}
1068+
}
1069+
1070+
if (!$needsSorting) {
1071+
return;
1072+
}
1073+
1074+
uksort($children, static function ($a, $b) use ($c): int {
1075+
return [$c[$b]['p'], $c[$a]['i']] <=> [$c[$a]['p'], $c[$b]['i']];
1076+
});
1077+
}
1078+
10521079
/**
10531080
* Normalizes the underlying data if a model transformer is set.
10541081
*

src/Symfony/Component/Form/Tests/Extension/Core/Type/FormTypeTest.php

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -836,6 +836,29 @@ public function testFormAttrAsStringWithNoId()
836836
$this->assertSame($view->vars['id'], $view['child1']->vars['attr']['form']);
837837
$this->assertSame($view->vars['id'], $view['child2']->vars['attr']['form']);
838838
}
839+
840+
public function testSortingViewChildrenBasedOnPriorityOption()
841+
{
842+
$view = $this->factory->createNamedBuilder('parent', self::TESTED_TYPE)
843+
->add('child1', null, ['priority' => -1])
844+
->add('child2')
845+
->add('child3', null, ['priority' => -1])
846+
->add('child4')
847+
->add('child5', null, ['priority' => 1])
848+
->add('child6')
849+
->getForm()
850+
->createView();
851+
852+
$expected = [
853+
'child5',
854+
'child2',
855+
'child4',
856+
'child6',
857+
'child1',
858+
'child3',
859+
];
860+
$this->assertSame($expected, array_keys($view->children));
861+
}
839862
}
840863

841864
class Money

src/Symfony/Component/Form/Tests/Fixtures/Descriptor/resolved_form_type_1.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@
5757
"mapped",
5858
"method",
5959
"post_max_size_message",
60+
"priority",
6061
"property_path",
6162
"required",
6263
"row_attr",

src/Symfony/Component/Form/Tests/Fixtures/Descriptor/resolved_form_type_1.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ Symfony\Component\Form\Extension\Core\Type\ChoiceType (Block prefix: "choice")
3434
mapped
3535
method
3636
post_max_size_message
37+
priority
3738
property_path
3839
required
3940
row_attr

src/Symfony/Component/Form/Tests/Fixtures/Descriptor/resolved_form_type_2.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
"mapped",
3636
"method",
3737
"post_max_size_message",
38+
"priority",
3839
"property_path",
3940
"required",
4041
"row_attr",

src/Symfony/Component/Form/Tests/Fixtures/Descriptor/resolved_form_type_2.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ Symfony\Component\Form\Extension\Core\Type\FormType (Block prefix: "form")
3737
mapped
3838
method
3939
post_max_size_message
40+
priority
4041
property_path
4142
required
4243
row_attr

0 commit comments

Comments
 (0)
0