如何创建两个相关的radiobuttons?

Ale*_*mia 5 symfony

下面的代码创建了2个radiobuttons,但它们彼此无关.一个用名字渲染,description_form[friend]另一个用名字 - description_form[guide].如何使用相同的名称呈现它们?该文件并未明确这个问题.

public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('friend', RadioType::class, array(
                'label'    => 'Friend',
                'required' => false
            ))
            ->add('guide', RadioType::class, array(
                'label'    => 'Guide',
                'required' => false
            ));
    }
Run Code Online (Sandbox Code Playgroud)

Hea*_*eah 8

使用列表RadioType并不容易,这就是为什么每个人都建议你使用一个ChoiceType根据选择数据数组动态创建一个无线电列表的原因.

创建a时FormTypeInterface,它必须(通常)以全局形式表示一个字段或一个子表单,因此每个字段名称必须唯一才能映射到相应的数据.

buildForm方法允许在您中添加一些子字段FormType,在您的情况下,该字段包含两个子字段作为单选按钮,每个子字段都有一个特定的名称,这是默认情况下的,但您应该始终牢记您想要的全局数组数据处理.

这是你的例子:

class MyCustomFormType extends \Symfony\Component\Form\AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('friend', RadioType::class, array(
                'label'    => 'Friend',
                'required' => false
            ))
            ->add('guide', RadioType::class, array(
                'label'    => 'Guide',
                'required' => false
            ));
    }

    public function getBlockPrefix
    {
        return 'my_custom';
    }

    // ...
}
Run Code Online (Sandbox Code Playgroud)

所以这个表单类型数据应该如下所示:

$myCustomFormData = array(
    'friend' => $friendData,
    'guide' => $guideData,
);
Run Code Online (Sandbox Code Playgroud)

并以全局形式嵌套,它将是:

$formData = array(
    'my_custom' => $myCustomFormData,
);
Run Code Online (Sandbox Code Playgroud)

但您可以根据需要命名字段:

// In a controller extending \Symfony\Bundle\FrameworkBundle\Controller\Controller
$form = $this->createFormBuilder()
    ->add('custom_field', MyCustomFormType::class)
    ->getForm();

// Then
$form->setData(array('custom_field' => $myCustomFormData));
Run Code Online (Sandbox Code Playgroud)

请注意,目前,由于您将"朋友"和"引导"数据映射到RadioType它们应该保持一个布尔值:

$myCustomFormData = array(
    'friend' => true, // checked
    'guide' => false, // unchecked
);
Run Code Online (Sandbox Code Playgroud)

但是你如何取消选择价值?

你应该有一个占位符来做,并在提交时处理它...

此外,可以使用finishView类型类的方法更改名称,它将FormView(类型的构建视图),表单本身和选项作为参数:

public function finishView(FormView $view, FormInterface $form, array $options)
{
    $childName = $view->vars['full_name']; // "my_custom" by default

    foreach ($view as $childView) {
        $childView->vars['full_name'] = $childName;
    }
}
Run Code Online (Sandbox Code Playgroud)

但是您还需要添加一个DataMapperInterface以将提交的值返回到表单类型本身.

要做到这一切,您需要知道表单组件的工作原理并不容易.

简单的方法

所以我同意其他答案,你应该用a ChoiceType来开箱即用.

我假设您的自定义表单类型是关于选择"朋友"或"指南",所以它可能如下所示:

$builder
    ->add('fellow', ChoiceType::class, array(
        'choices' => array(
            'I have a friend' => 'friend',
            'I\'d like a guide' => 'guide',
        ),
        'expanded' => true, // use a radio list instead of a select input
        // ...
Run Code Online (Sandbox Code Playgroud)

看看官方文档

然后您的数据将如下所示:

$form->add('custom_field', MyCustomFormType::class);

$form->setData(array(
    'custom_field' => 'friend',
));
Run Code Online (Sandbox Code Playgroud)

渲染时,将选择"朋友"选项,您将能够将其更改为"指南".

选项的一系列choices选项将标签作为键和选择值作为值:

<div id="form_custom_field">
    <input type="radio" name="form[custom_field]" value="friend" checked="checked">
    <label>I have a friend</label> 
    <input type="radio" name="form[custom_field]" value="guide">
    <label>I'd like a guide</label>

... 
Run Code Online (Sandbox Code Playgroud)