0

我在 Symfony 中制作了一个未绑定到实体的表单。其中一个表单元素是一组复选框fieldtypes。显示哪些字段类型复选框应取决于searchby字段的值。我想为每个复选框添加一个类,以用作稍后添加的 javascript 的显示/隐藏挂钩。但就我所见,选择表单元素只允许应用一个整体类。

这是我的表格的相关部分:

$form = $this->createFormBuilder()
    ->add('searchby', 'choice', array(
            'label' => 'browse.label.searchby',
            'choices'=>array(
                'name'              => 'browse.searchby.name',
                'location'          => 'browse.searchby.location',
                'classification'    => 'browse.searchby.classification'
                    ),
            'required' => true,
            'multiple' => false,
            'expanded' => true,
                    ))
    ->add('fieldtypes', 'choice', array(
            'label' => 'browse.label.fieldtypes',
            'choices' => array(
                'extensionAttribute12'      =>  'person.label.position.fr',
                'title'                     =>  'person.label.position.eng',
                'l'                         =>  'person.label.city',
                'st'                        =>  'person.label.province',
                'co'                        =>  'person.label.country',
                'givenname'                 =>  'person.label.firstname',
                'sn'                        =>  'person.label.lastname',
                'name'                      =>  'person.label.fullname',
                ),
            'required' => true,
            'multiple' => true,
            'expanded' => true
                    ));

如果我想将“searchbyname”类添加到从中创建的单选按钮中$options['choices']['givenname'], $options['choices']['sn'], $options['choices']['name'],我将如何处理?

4

1 回答 1

1

看到可以这样声明选择之后:

'choices' => array(
        'classification'    => array(
            'extensionAttribute12'      =>  'person.label.position.fr',
            'title'                     =>  'person.label.position.eng',
            ),
        'location'  => array(
            'l'                         =>  'person.label.city',
            'st'                        =>  'person.label.province',
            'co'                        =>  'person.label.country',
        ),
        'name'  =>  array(
            'givenname'                 =>  'person.label.firstname',
            'sn'                        =>  'person.label.lastname',
            'name'                      =>  'person.label.fullname',
        )
    ),

其中每个子数组的键将用作 a 中的<optgroup>标签<select>;在尝试修改 Twig 模板(正如@Cerad 所说的那样,这有点痛苦)之后,我尝试通过创建表单类型扩展来扩展 ChoiceType 类。

我的解决方案效率低下,因为我在创建子视图后修改它们,而且我必须包含来自ChoiceType::finishView. 我看不到子视图是如何创建的。有一行ChoiceType::buildForm读取$remainingViews = $options['choice_list']->getRemainingViews();,但由于$options['choices']作为数组输入,我不知道getRemainingViews()从哪个类调用。

无论如何,这里是:

<?php
namespace Expertise\DefaultBundle\Form\Extension;

use Symfony\Component\Form\AbstractTypeExtension;
use Symfony\Component\Form\FormView;
use Symfony\Component\Form\FormInterface;
use Symfony\Component\PropertyAccess\PropertyAccess;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;


class ChoiceTypeExtension extends AbstractTypeExtension
{
    /**
     * @return string The name of the type being extended
     */
    public function getExtendedType()
    {
        return 'choice';
    }

    public function setDefaultOptions(OptionsResolverInterface $resolver)
    {
        $resolver->setOptional(array('optgroup_as_class'));
        $resolver->setDefaults(array('optgroup_as_class'=>false));
    }


    public function finishView(FormView $view, FormInterface $form, array $options)
    {

        if ($options['expanded']) {
            // Radio buttons should have the same name as the parent
            $childName = $view->vars['full_name'];

            // Checkboxes should append "[]" to allow multiple selection
            if ($options['multiple']) {
                $childName .= '[]';
            }

            foreach ($view as $childView) {
                $childView->vars['full_name'] = $childName;
                if($options['optgroup_as_class']){
                    foreach($options['choices'] as $optclass => $choices){
                        if(!is_array($choices)) continue;
                        foreach($choices as $value => $label){
                            if($childView->vars['value'] == $value && $childView->vars['label'] == $label) {
                                $childView->vars['attr']['class'] =  $optclass;
                                break 2;
                            }
                        }
                    }
                }
            }
        }
    }
}

将其添加为服务,使用“optgroup”choices格式并设置optgroup_as_class为 true。

我很想看到一种更有效的方法。

于 2013-08-15T17:46:24.960 回答