-
-
Notifications
You must be signed in to change notification settings - Fork 9.6k
[Form] Add support for sorting fields #40690
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
025aba9
to
ce8398f
Compare
src/Symfony/Component/Form/Form.php
Outdated
} | ||
|
||
uksort($children, static function ($a, $b) use ($c): int { | ||
return $c[$a]['w'] === $c[$b]['w'] ? $c[$a]['n'] <=> $c[$b]['n'] : $c[$a]['w'] <=> $c[$b]['w']; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For PHP < 8.0 *sort() functions don't apply a stable sorting to keep equals elements in the original order https://3v4l.org/NQtul. That's why I needed to take care about it here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this can be written as return [$c[$a]['w'], $c[$a]['n']] <=> [$c[$b]['w'], $c[$b]['n']];
Arrays are sorted by comparing their values one by one
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nicer 😍 ! - Updated.
I like that this diff is only (+53 -2). I agree that this could be a simple way to control the rendering of the form. It will allow me to render more forms as On most other places we use the word |
Nice proposal Yonel 😃🎉 I thought about the priority too but the explanation with "weight" and "sink down" is super power. I find myself asking the question quite often: negative or positive priority, but if I think of a weight it makes things much easier and more clear. I like the wording, plus it's a setting for something "visual", which is not the case for priority 🙂 |
Wow! thanks for your fast review :) I find "the field weight" pretty clear, but I'm open to change it if we all agree with another name.
Yes, "priority" could be another name and it should be interpreted as "the field rendering priority". Let's way for other opinions if it's really clearer than "weight" or for terminology consistency. |
We use "priority" more commonly, I think it would be more consistent to use it. |
ce8398f
to
be75330
Compare
be75330
to
ee71072
Compare
PR updated with |
ee71072
to
40e1766
Compare
@@ -1044,11 +1044,29 @@ public function createView(FormView $parent = null) | |||
$view->children[$name] = $child->createView($view); | |||
} | |||
|
|||
$this->sort($view->children); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should this be done before or after finishView
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
From my point of view, this should be done before finishView()
.
- This is the final step of the view creation, thus I don't expect any view change after that.
- In case you want to change the current order to anything else (custom conditions) you could do it in
finishView()
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Indeed, if you have a type extension doing this currently (sorting fields on finishView
by a custom criteria), we will break that chance if we sort after finishView
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
makes sense
40e1766
to
3c61c6e
Compare
Comments addressed, thanks! |
This is a really great proposal and a non-invasive implementation. Great work! 🎉 I had this functionality in an external bundle in use for several years now and the most common use case for me was a Is that a feature that is possible to add / planned? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
<3
That feature is not currently in the pipe and it will not be covered in this PR. |
The bundle @apfelbox is talking about is https://github.com/becklyn/OrderedFormBundle. Yes, I'm biased in this regards since this is our company's bundle, but I still vastly prefer a more explicit and relative API (the one from our bundle) over a We wouldn't mind if our bundle (or rather the functionality of it) would become part of Symfony's core :) |
8d4ea0a
to
62650bb
Compare
Thank you. @keichinger, that is a great bundle. Let's consider this PR baby steps and if we want to see the bundle's feature in Symfony, then I suggest to open a new issue. =) |
This PR was merged into the 5.3-dev branch. Discussion ---------- [Form] Documenting new priority option PR: symfony/symfony#40690 Fix: symfony#15239 Commits ------- 454087d Documenting form field priority option
@yceruto why is the sorting done in I discovered the Referring back to this comment by @Nyholm:
That makes the feature currently broken, because indeed I was expecting a high priority to mean it would be HANDLED first, as everywhere else in Symfony. Instead it is only rendered first, in some situations, and completely ignored while handling. Currently it functions as Further confusing is that the draw order and handle priority would in my use case not even be identical, the dependent element is drawn first for UX reasons. So I think the whole concept of |
Well, the feature request was always about the rendering, not about the handling. That's why it was only implemented as part of the form view creation. |
This PR adds a new
priority
option used later to sort all fields in order of importance instead of simply numerical order, i.e. fields with higher priority will be rendered first, fields with lower priority will be rendered last. The default priority would be "0" for all fields. Fields with equal priority will keep the original order (stable sorting).History of previous proposals and discussions: #3452, #4254, #5827, #6111, #11241
This kind of feature has been abandoned in the past because complex proposals, and somehow rejected because ideally we should do the sorting at the view level (customizing form themes or layout templates) and it's true for most cases (the simple ones I think) but the fact is that it's often quite complex to accomplish that way, mainly for dynamic forms.
Let's focus the following analysis on explaining why and when the
priority
option could save us a lot of time, getting rid of cumbersome workarounds with templates to change the rendering order only.A common example could be the building of a multi-steps form with a convenient type hierarchy and including fields dynamically based on the data. Let's take this sample:
These classes model the required form. However, according to the form building process and taken into account that the underlaying person data was set with "legal" type (from the previous step), this will be the rendering result:
Now, taking the view customization path to fix the order, you likely will face some problems regarding to:
There could be more and different problems depending on the context and you can find workarounds using the block prefixes system to customize each step block theme, but to me it's enough to think about other alternatives.
On the other side, using the
priority
option, the solution is quite easy. Setting the right priority value will guarantee the right rendering order:That's ! There is no need to customize templates at all when you only need to change the fields order.
This way, these fields are being pre-defined in the order they will be rendered at view level. This sorting process will take place on
$form->createView()
method, just afterbuildView()
and beforefinishView()
calls.Could we reconsider the usefulness of this feature? please.
Cheers!