0

エンティティにバインドされていないフォームを Symfony で作成しました。フォーム要素の 1 つは、一連のチェックボックスであるfieldtypesです。どのfieldtypeチェックボックスが表示されるかは、 searchbyフィールドの値によって異なります。各チェックボックスにクラスを追加して、後で追加する JavaScript の表示/非表示フックとして使用したいと考えています。しかし、私が見る限り、choicesフォーム要素では、クラス全体を適用することしかできません。

これが私のフォームの関連部分です:

$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',
        )
    ),

各サブ配列のキーは;の<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 に答える