Symfony基本上呈现
entity
field type类choice
下拉列表 -select
。但是,我正在使用的CSS框架将一种“选择”定义为ul
和li
作为选项。 Custom Field Type文档没有提供有关此方案的帮助。
我正在使用twig和form_widget()
将我的代码从表单下拉列表的手动HTML呈现转换为symfony表单的版本。但是,我想要ul
和li
而不是select
。
创建下拉列表的手动方式是:
<ul class='dropdown-menu'>
{% for locator in locators %}
<li>
<a href="#" data-id="{{locator.getId() }}">
{{ locator.getName() }}
</a>
</li>
{% endfor %}
</ul>
这就是我在使用symfony表单之前手动渲染下拉列表的方法。它看起来像这样:
我喜欢它。我认为它看起来很棒。现在,如果我使用Symfony表单,我可以使用它:
{{ form_start(form) }}
{{ form_widget(form.locator) }} {# This is my locator dropdown #}
{{ form_widget(form.target) }} {# Ignore this #}
{{ form_end(form) }}
问题是这会改为:
我无法在此处添加自定义CSS,因为它会呈现为select
,而不是无序列表和li
。
如果它有帮助,这是我的表单类型:
/**
* {@inheritDoc}
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('target')
->add('locator', 'entity', [
'class' => 'Application\Model\Entity\Locator',
'query_builder' => function(EntityRepository $repo) {
return $repo->createQueryBuilder('e');
},
'empty_value' => 'Locator'
])
->add('save', 'submit', ['label' => 'Save']);
$builder->setAction($this->urlGenerator->generate('page_create_element', [
'suiteId' => $options['suiteId'], 'pageId' => $options['pageId']
]))->setMethod('POST');
}
问题:有什么方法可以让上面的表单命令自动生成我的ul / li需求而不是选择,或者我必须手动渲染它而忽略symfony表单这个组件?
答案 0 :(得分:2)
感谢上面的一些海报,有一些来自Form Theming的信息,但它还不够完整,所以我不得不在github上进行一些挖掘。
根据documentation,Symfony使用twig模板来呈现表单的相关位,并且它包含元素。这些只是{% block %}
在树枝上。因此,第一步是找到在symfony代码库中呈现选择按钮的位置。
首先,您在其自己的twig文件中创建自己的主题块,然后使用以下代码将此主题应用于表单:
{% form_theme my_form_name 'form/file_to_overridewith.html.twig %}
因此,如果我在上面的文件中覆盖了{% block form_row %}
,那么当我调用{{ form_row(form) }}
时,它将使用我的块而不是Symfony的默认块。
重要提示:您不必覆盖所有内容。只需覆盖您想要更改的内容,如果Symfony在您的主题中找不到它,它将回归到它自己的块。
在github上,我找到了source code用于Symfony&#34;选择小部件&#34;。这有点复杂,但是如果你仔细研究并尝试一下,你会看到它的去向。
在choice_widget_collapsed
块中,我将选择更改为ul
并将选项更改为li
。这是我创建的主题文件,请注意上面描述的细微差别:
{# Symfony renders a 'choice' or 'entity' field as a select dropdown - this changes it to ul/li's for our own CSS #}
{%- block choice_widget_collapsed -%}
{%- if required and empty_value is none and not empty_value_in_choices and not multiple -%}
{% set required = false %}
{%- endif -%}
<ul {{ block('widget_attributes') }}{% if multiple %} multiple="multiple"{% endif %}>
{%- if preferred_choices|length > 0 -%}
{% set options = preferred_choices %}
{{- block('choice_widget_options') -}}
{%- if choices|length > 0 and separator is not none -%}
<li disabled="disabled">{{ separator }}</li>
{%- endif -%}
{%- endif -%}
{%- set options = choices -%}
{{- block('choice_widget_options') -}}
</ul>
{%- endblock choice_widget_collapsed -%}
{%- block choice_widget_options -%}
{% for group_label, choice in options %}
{%- if choice is iterable -%}
<optgroup label="{{ group_label|trans({}, translation_domain) }}">
{% set options = choice %}
{{- block('choice_widget_options') -}}
</optgroup>
{%- else -%}
<li value="{{ choice.value }}"{% if choice is selectedchoice(value) %} selected="selected"{% endif %}><a href="#">{{ choice.label|trans({}, translation_domain) }}</a></li>
{%- endif -%}
{% endfor %}
{%- endblock choice_widget_options -%}
现在我可以使用以下内容呈现我的表单:
{{ form_widget(form.locator, {'attr': {'class': 'dropdown-menu'}}) }}
这使用我的主题作为选择下拉列表,其中包含ul
和li
标记,而不是select
和option
标记。一旦你知道在哪里寻找原始代码就很简单!呈现的HTML:
<ul id="elementtype_locator" name="elementtype[locator]" required="required" class="dropdown-menu">
<li value="1"><a href="#">id</a></li>
<li value="2"><a href="#">name</a></li>
<li value="3"><a href="#">xpath</a></li>
</ul>
我还必须删除其中一条放置“定位器”的线路。在下拉列表的顶部,因为有四个下拉选项(包括empty_data一个)而不是三个。