问题
I would like a <select>
element to be rendered with additional data on its <option>
s. For the sake of example, I'd like to have a service-selector (non-multiple entity-field) that resets another inputs value upon selection change. I'm not interested in using JS data-structures, I need to have the rendered field to look as follows:
<select name="...">
<option value="1" data-price="90">Service 1</option>
<option value="2" data-price="40">Service 2</option>
</select>
I would take two different solutions and would be glad to see the answer to both of them.
- I'd render the field manually in Twig by starting to assemble the above HTML code by using the
form
variable I passed to the twig. I have two problems solving this. A) I can't find a safe way to tell what the filed should be named, i.e. how do I get thename
attribute that Symfony expects by using the variableform.service
(service is the name of the field in the FormType). [Please spare me tricks that concatenate some values based on observing how fields are currently named by Symfony; one should rely on interfaces and not on reverse engineering.] B) I don't know how to access the list of choices, i.e. the array assembled by theentity
field'squery_builder
option. [Since I'm looking for a general solution, I'm not willing to duplicate these items over to a twig-parameter in the controller -- just to avoid such suggestions.] - I'd override the rendering of the relevant field blocks, as suggested in the form styling chapter of the cookbook, but there are three problems with that. A) I cannot find out which blocks should be overridden (and so I don't find samples). B) I would pass parameter from the form builder to the block to let it know what extra
data-
attributes are to be rendered, but I don't know how to do this. And finally C) in those cases where I don't need to deviate from standard rendering (e.g. when the field is multiple) I don't know how to fallback to the default rendering.
So these are actually 5 questions (1A,1B,2A,2B,2C) but I thought them to be more useful to others answered together, since they all address what I think is an undocumented spot regarding choice field rendering.
回答1:
1. Manually rendering. Better if is a individual form for field and not repeated somethere as it requires less time to work.
A) Get name of field you can with form.service.vars.full_name
B) List of choices - form.service.vars.choices
. Its an array of ChoiceView
, to get entity simply access public data
property.
{% for choice in form.service.vars.choices %}
{% set service_entity = choice.data %}
{% endfor %}
2. Via overriding templates. IF you like to brute-force pick up the name of the blocks which must be overriden.
A) You can only override widget
, label
and errors
blocks as documentation said. You can specify block by widget name(documentation). Something like
{% block _form_service_widget %}
{% if expanded %}
{{ block('choice_widget_expanded') }}
{% else %}
{{ block('my_service_widget') }}
{% endif %}
{% endblock %}
{% block my_service_widget %}
{% spaceless %}
<select {{ block('widget_attributes') }}{% if multiple %} multiple="multiple"{% endif %}>
{% if empty_value is not none %}
<option value="">{{ empty_value|trans({}, translation_domain) }}</option>
{% endif %}
{% set options = choices %}
{{ block('my_service_options') }}
</select>
{% endspaceless %}
{% endblock my_service_widget %}
{% block my_service_options %}
{% spaceless %}
{% for group_label, choice in options %}
{# here you can access choice #}
<option value="{{ choice.value }}"{% if choice is selectedchoice(value) %} selected="selected"{% endif %}>{{ choice.label|trans({}, translation_domain) }}</option>
{% endfor %}
{% endspaceless %}
{% endblock my_service_options %}
回答2:
You can use the choice_attr
option in the form builder:
$builder->add('myField', ChoiceType:class, [
....
'choice_attr' => function($val, $key, $index) {
return ['data' => '...', 'class' => '', ... etc ];
},
....
]);
This will apply attributes to each option
, checkbox
, radio
in your choice (depending on your expanded
and multiple
option choices)
来源:https://stackoverflow.com/questions/15684751/customize-the-rendering-of-a-choice-entity-field-in-symfony2