Skip to content

[Form] Example of customizing EnumType labels #17149

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

Merged
merged 1 commit into from
Dec 13, 2022

Conversation

robinbrisa
Copy link
Contributor

Default behavior when creating a EnumType form element is that the choice labels displayed to the user are the enum names.

This PR adds an example of how to use a function inside an enum to return labels and how to bind this function to the form element.

case Center = 'Center/Middle aligned';
case Right = 'Right/End aligned';

public function label(): string
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Adding this method to the enum class starts mixing data and presentation which I would not advise. Let's configure the choice label using a closure instead (see comment below).

->add('textAlign', EnumType::class, [
'class' => TextAlign::class,
'choice_label' => static function (TextAlign $choice): string {
return $choice->label();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
return $choice->label();
return match ($choice) {
TextAlign::Left => 'text_align.left.label',
TextAlign::Center => 'text_align.center.label',
TextAlign::Right => 'text_align.right.label',
};

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This would work if you only needed to display the labels in your form, but if you also need them to appear anywhere else in your application I think adding a method in the enum class is a better solution. I don't think adding presentation methods in enum classes is a bad practice.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If I had different places where I needed the label, I would go with a separate class that maps enum instances to labels to be honest.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That might be a way to do it but maybe a bit overkill. Even the PHP documentation suggests adding a label method in enum classes in their examples : https://www.php.net/manual/fr/language.enumerations.examples.php

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't know what to say here. I think both of you gave good reasons to do opposite things.

Let's ask @wouterj and @OskarStark. Thanks!

Copy link
Member

@wouterj wouterj Oct 6, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree with @xabbuh here. I understand your point, @robinbrisa, and it is also proven by the official PHP docs.

However, I would say that an enum can ship a generic presentation layer. The labels provided in this example indirectly couple the Enum's presentation layer to the Symfony Translation component - without it, the labels render worse human readable than their default string representation from the BackedEnum.
In that case, I would favor to keep the enum decoupled from Symfony Translation and handle the presentation in the layer that is responsible for mapping between Symfony Translation and the Enum, which is this function :)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Another way to see it would be to have MyEnum::getLabel() and/or MyEnum::getTranslationKey() to make it more reusable with respect for different layers.
However for the docs I agree this callable is a good way to go.

@robinbrisa robinbrisa requested a review from xabbuh August 11, 2022 08:05
@OskarStark OskarStark changed the title [Form] Example of customizing EnumType labels [Form] Example of customizing EnumType labels Oct 5, 2022
'choice_label' => static function (TextAlign $choice): string {
return $choice->label();
},
])
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
])
]);

@javiereguiluz javiereguiluz added this to the 5.4 milestone Dec 13, 2022
Default behavior when creating a EnumType form element is that the choice labels displayed to the user are the enum names. 

This PR adds an example of how to use a function inside an enum to return labels and how to bind this function to the form element.
@javiereguiluz javiereguiluz changed the base branch from 6.1 to 5.4 December 13, 2022 16:21
@javiereguiluz javiereguiluz merged commit fa2dfc8 into symfony:5.4 Dec 13, 2022
@javiereguiluz
Copy link
Member

Robin, thanks and congrats on your first Symfony Docs contribution 🎉

@xabbuh @wouterj @HeahDude thanks for the review. I did the requested changes while merging (see c4de976)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants