在 Symfony FormBuilder 中添加 class 到 select 选项

Add class to select option in Symfony FormBuilder

在我的 Symfony 2 应用程序中,我使用 FormBuilder 为生成的文档中包含的数据创建一个表单。select

$typeChoices = [
    '001' => 'first factor',
    '002' => 'another factor',
    '003' => 'some surcharge',
    '004' => 'custom discount',
    '005' => 'another surcharge'
];

$formDownload = $this->createFormBuilder(array())
    ->add('category', 'entity', array(
        'class' => 'MyApp\CategoryBundle\Entity\Category',
        'choice_label' => 'name'
    ))
    ->add('type', 'choice', array(
        'choices' => $typeChoices,
        'multiple' => true
    ))
    ->add('download', 'submit', array(
        'attr' => array(
            'class' => 'btn-primary'
        ),
    ))
    ->setAction($this->generateUrl('myapp_data_download'))
    ->getForm();

$typeChoices 数据是从 EntityRepository 加载的 - 我只是简化了此演示的代码。

这样就生成了一个select框:

<select multiple="multiple" class="form-control" required="required" name="form[type][]" id="form_type">
    <option value="001">first factor</option>
    <option value="002">another factor</option>
    <option value="003">some surcharge</option>
    <option value="004">custom discount</option>
    <option value="005">another surcharge</option>
</select>

如何为每个 option 添加 class 属性?它必须基于来自 EntityRepository 的原始数据的属性创建。直到现在,我无法在使用 FormBuilder 时向 option 添加 class 属性,我想避免手动创建表单标记。

Symfony 2.7 中的新功能:Choice form type refactorization

In Symfony 2.7 this form type has been completely refactored to support dynamic generation for labels, values, indexes and attributes. This is now possible thanks to the new options choice_label, choice_name, choice_value, choice_attr, group_by and choices_as_values.

例如,您可以生成动态选择标签

示例:

$builder->add('attending', 'choice', array(
    'choices' => array(
        'yes' => true,
        'no' => false,
        'maybe' => null,
    ),
    'choices_as_values' => true,
    'choice_label' => function ($allChoices, $currentChoiceKey) {
        return 'form.choice.'.$currentChoiceKey;
    },
));

在您的情况下,您希望操纵每个选项的属性class

示例:

$builder->add('attending', 'choice', array(
    'choices' => array(
        'Yes' => true,
        'No' => false,
        'Maybe' => null,
    ),
    'choices_as_values' => true,
    'choice_attr' => function ($allChoices, $currentChoiceKey) {
        if (null === $currentChoiceKey) {
            return array('class' => 'text-muted');
        }
    },
));

希望对您有所帮助。

在表单中添加 Symfony\Component\Form\AbstractType::finishView class

/**
 * @param FormView $view
 * @param FormInterface $form
 * @param array $options
 */
public function finishView(FormView $view, FormInterface $form, array $options)
{
    parent::finishView($view, $form, $options);

    $additionalAttributes = array();

    // myMethod - object method $choice, returns a value that must be replaced by attribute
    foreach ($view->children['type']->vars['choices'] as $id => $choice) {
        $additionalAttributes[$id] = array(
            'class' => $this->propertyAccessor->getValue($choice->data, 'myMethod'),
        );
    }

    foreach ($view->children['type']->children as $id => $child) {
        $child->vars['attr'] = array_replace(
            isset($child->vars['attr']) ? $child->vars['attr'] : array(),
            $additionalAttributes[$id]
        );
    }
}

Symfony2 Form - adding an attribute to the tag option in the select type