Symfony2:如何将使用工厂构建器创建的表单添加到另一个表单的集合类型字段中?

时间:2017-03-21 16:51:20

标签: php forms symfony symfony-2.7

我在运行时从yml创建表单。我浏览yml文件中的元素并向表单添加适当的字段。根表单就像这样创建

$form = $factory->createBuilder("form", $this->userData);

yml也可以选择定义集合字段。 集合字段需要提供type选项,该选项必须是stringSymfony\Component\Form\ResolvedFormTypeInterfaceSymfony\Component\Form\FormTypeInterface

类型

但是因为我在运行时也在构建嵌入式表单,所以我没有类型,也没有FormTypeInterface

以下是我需要做的示例代码

$options = isset($config["options"]) ? $config["options"]: [];
if ($config['type'] == 'collection') {
    $options['type'] = $this->buildForm($options['template'], $factory);
    unset($options['template']);
    $form->add($config["name"], $config["type"], $options);
}

这里$options['template']是如何在yml文件中定义嵌入表单的类型。因此,该表单也在运行时构建。如何将其嵌入根表单中?

编辑: 事实上,如果我只有一个字段,在集合字段中说email,那么它可以正常工作。但yml规范将允许用户在集合字段中定义多个字段。在symfony中,这可以通过定义嵌入的表单类型并将集合字段类型的type选项设置为该表单类型来完成。但是如何在运行时创建表单时这样做呢?

1 个答案:

答案 0 :(得分:0)

我通过定义一个表单类型来解决它,它在运行时构建表单。 config(表单设计)传递给构造函数,typedef int16_t int_type; // now using 16 bit integers 根据设计添加相应的字段。

 <script type="text/javascript">
   $(document).ready(function() {
       $("form#my_form").submit(function() {
         $('button[type=submit], input[type=submit]').prop('disabled',true);
         return true;
       });
   });
 </script>

并在构建器中,当类型为buildForm时,类型初始化此表单类型并添加到根表单。

class RuntimeFormType extends AbstractType
{
    /**
     * @var string
     */
    private $name;

    /**
     * @var array
     */
    private $config;

    /**
     * RuntimeFormType constructor.
     * @param string $name
     * @param array $config
     */
    public function __construct($name, array $config)
    {
        $this->name = $name;
        $this->config = $config;
    }

    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        foreach($this->config as $config){
            $options = isset($config["options"]) ? $config["options"]: [];

            if($config['type'] == 'image'){
                $options['data_class']  = null;
                $options['multiple']  = false;

                $options['attr'] = [
                    "accept" => "images/*"
                ];

                $builder->add($config["name"], "file", $options);
            }else{
                $builder->add($config["name"], $config["type"], $options);
            }
        }
    }


    public function getName()
    {
        return $this->name;
    }
}