dongzhan7253 2017-03-21 16:51
浏览 79
已采纳

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

I am creating forms from yml at runtime. I go through the elements in yml file and add appropriate fields to the form. The root form is created like this

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

The yml will have an option to define a collection field as well. The collection field requires type option to be supplied which must be of type string, Symfony\Component\Form\ResolvedFormTypeInterface, Symfony\Component\Form\FormTypeInterface

But since I am building the embedded form as well at runtime, I wont have a type and neither FormTypeInterface

Here is the sample code of what I need to do

$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);
}

Here $options['template'] is how the type for the embedded form is defined in yml file. So that form is also build at runtime. How do I embed it in the root form?

Edit: In fact, if I only have a single field, say email in the collection field, then it works fine. But the yml spec will allow users to define multiple fields within collection fields. In symfony, this would be done by defining the embedded form type and setting type option of collection field type to that form type. But how do I do it when creating forms at runtime?

  • 写回答

1条回答 默认 最新

  • dtkp51520 2017-03-22 06:26
    关注

    I solved it by defining a form type class, that builds the form at runtime. The config(form design) is passed into the constructor and buildForm adds respective fields according to the design.

    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;
        }
    }
    

    and in the builder, when the type is collection type initialize this form type and add to the root form.

    if ($config['type'] == 'collection') {
        $template = $options['template'];
    
        unset($options['template']);
        $options['type'] = new RuntimeFormType($config["name"], $template);
    
        $form->add($themeConfig["name"], $themeConfig["type"], $options);
    }
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 pyqt怎么把滑块和输入框相互绑定,求解决!
  • ¥20 wpf datagrid单元闪烁效果失灵
  • ¥15 券商软件上市公司信息获取问题
  • ¥100 ensp启动设备蓝屏,代码clock_watchdog_timeout
  • ¥15 Android studio AVD启动不了
  • ¥15 陆空双模式无人机怎么做
  • ¥15 想咨询点问题,与算法转换,负荷预测,数字孪生有关
  • ¥15 C#中的编译平台的区别影响
  • ¥15 软件供应链安全是跟可靠性有关还是跟安全性有关?
  • ¥15 电脑蓝屏logfilessrtsrttrail问题