symfony - 从 ChoiceType 扩展的自定义类型 Enum。Symfony
问题描述
在表单的类型中,使用了自定义类型“enum”。当我在表单选择中选择一个值并保存它时,当我在选择中重新打开表单时,这个值不会排在第一位。例如,如果我选择“次要”保存并再次打开表单,那么首先在选择中它仍然是“主要”。如何将实例的值放在select的首位?
/**
* Class SomethingType
*
* @method static SomethingType PRIMARY()
* @method static SomethingType SECONDARY()
*/
final class SomethingType extends AbstractEnum
{
const PRIMARY = 'primary';
const SECONDARY = 'secondary';
}
在自定义类型中:
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('type', 'enum', [
'class' => 'SomethingType',
]);
}
枚举:
class EnumType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->resetViewTransformers()
->addModelTransformer(new EnumTransformer($options['class']));
}
/**
* @param OptionsResolver $resolver Validates options and merges them with
* default values.
* @return void
*/
public function configureOptions(OptionsResolver $resolver)
{
$resolver
->setDefined('class')
->setDefault('choices', function (Options $options) {
$data = [];
if (isset($options['class'])) {
$enum = call_user_func($options['class'] . '::values');
/** @var AbstractEnum $item */
foreach ($enum as $item) {
$value = $item->getValue();
$data[$value] = $value;
}
}
return $data;
});
}
public function getParent()
{
return 'choice';
}
public function getName()
{
return $this->getBlockPrefix();
}
public function getBlockPrefix()
{
return 'enum';
}
}
解决方案
您应该创建自定义树枝模板:
{% block enum_widget %}
{% if form is defined %}
{% if instanceof(form.vars.value, 'AbstractEnum') %}
{% spaceless %}
{%- set currentValue = form.vars.value.getValue -%}
<select {{ block('widget_attributes') }}{% if multiple %} multiple="multiple"{% endif %}>
{%- set options = choices -%}
{% for group_label, choice in options %}
<option value="{{ choice.value }}"
{% if choice.attr %}{% with { attr: choice.attr } %}{{ block('attributes') }}{% endwith %}{% endif %}
{% if choice.value == currentValue %} selected="selected"{% endif %}>
{{ choice_translation_domain is same as(false) ? choice.label : choice.label|trans({}, choice_translation_domain) }}
</option>
{% endfor %}
</select>
{% endspaceless %}
{% else %}
{{ block('choice_widget') }}
{% endif %}
{% endif %}
{% endblock %}
推荐阅读
- javascript - 在列表文本装饰中悬停文本不起作用
- c - 在没有 CRT 编译的程序中,是否可以通过 argv 读取命令行参数?
- python - 如果我在代理后面,如何使用 Basket 下载 python 库?
- powershell - Powershell 开关为空或为空
- python - python异常出错除了块
- forms - Symfony4 - 如何使用选民过滤 EntityType 字段
- spring - 如果我使用反应式客户端,服务器也应该是反应式的吗?
- tfs - 如果子文件夹映射到其他地方,为什么 TFS 不下载子文件夹
- c# - 如何获取单面墙的几何信息?
- ssh - 当服务器只允许键盘交互身份验证时,有没有办法进行 SSH 无密码登录?