Symfony2动态表单生成 [英] Symfony2 dynamic form generation

查看:113
本文介绍了Symfony2动态表单生成的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有mysql 2表格: user_profile_field user_profile_data 列出以下列:



user_profile_field:

  -id(integer)
-field(string)
-category )

user_profile_data:

  -id(integer)
-user_id(整数)
-field_id(整数)引用user_profile_field(id)
-data(string)

我还定义了映射此关系的2个Doctrine实体。我需要动态地创建一个更新user_profile_data的表单。 user_profile_field的每一行的表单输入类型取决于user_profile_field:category列(3个可能的值对应于不同的输入类型:text,textarea和choice字段)...



我不知道如何通过'Symfony2'方式创建表单和表单类型实体?



任何帮助或建议赞赏...

解决方案

我使用的早期解决方案是将定义表单配置的数组传递给表单类型的构造方法,并在buildForm方法中构建这些表单字段。 p>

我不知道你如何设置你的用户,所以你需要填写一些空白。


$ b $作为一个开始,我认为这将发生在控制器中,但更好的方法是像FOS用户包那样向Form处理程序提供更多的逻辑:
https://github.com/FriendsOfSymfony/FOSUserBundle/blob/master/Form/Handler/RegistrationFormHandler.php



您将需要获取所有用户配置文件字段并准备好数组,准备添加到表单类型构造函数(请参阅ProfileType的示例)。

  $ form_config = array(
'fields'=> array()
);

//将所有user_profile_field实体添加到$ form_config ['fields']
// foreach $ user_profile_fields as $ user_profile_field ...
// $ form_config ['fields '] [] = $ user_profile_field;

然后,您需要根据您收集的user_profile_data创建用户的数组表示形式。这个数据然后绑定到下面的表单。



我不知道你是否可以直接将这个数组版本传递给表单。如果表单期望一个实体,您可能需要先将基本用户实体传递到表单,然后绑定数组版本(包含动态数据)以设置动态字段值。



这是您将使用的Profile表单类:

  class ProfileType extends AbstractType 
{
//存储表单配置
//优选地图默认在这里或在getDefaultConfig方法
private $ formConfig = array();

//接受表单配置的新构造方法
public function __construct($ form_config = array())
{
//将传入的配置与默认
//将合并的数组设置为$ this-> formConfig
$ this-> formConfig = $ form_config;
}

public function buildForm(FormBuilder $ builder,array $ options)
{
//在这里添加任何强制成员字段
// $ builder - > add(...);

//遍历传递给构造函数的表单字段
//假设字段是user_profile_field实体的数组
foreach($ this-> formConfig ['字段']作为$字段){
// as form不是一个直的实体形式,我们需要设置这个
//否则验证可能有问题
$ options = array('property_path' => false);
//如果它的选择字段为$ options

$ builder-> add($ field-> getField(),$ field-> getCategory( ),$ options);
}

}

这涵盖表单的输出



在控制器中创建表单。

  $ profileForm = $ this-> createForm(new ProfileType($ form_config),$ user); 

总而言之,控制器方法应该像这样结构(填写空白):

  //获取用户
//获取用户数据
//创建数据版本的用户数据为一个副本

//获取配置文件字段
//将它们添加到表单config
//创建表单并将表单配置传递给构造函数,用户实体创建Form
//绑定数组版本的用户数据以形成填充动态字段的值


//检查表单是否有效
//做什么需要设置将表单数据发布给用户的数据
//更新用户和重定向

我觉得表单事件可能是更好的Symfony2方法,但这可能有助于您入门。然后,您可以在重构阶段考虑表单事件。


I have mysql 2 tables: user_profile_field and user_profile_data with following columns:

user_profile_field:

-id (integer)
-field (string)
-category(string) 

user_profile_data:

-id (integer)
-user_id (integer)
-field_id (integer) references user_profile_field(id)
-data (string)

I also have defined 2 Doctrine entities that map this relation. I need dynamicaly to create a form for updating user_profile_data. The form input type for each row of user_profile_field depends on user_profile_field:category column (3 possible values correspond to different input types: text, textarea and choice field) ...

Im not sure how to create the form and form type entity via 'Symfony2' way ?

Any help or suggestion appreciated ...

解决方案

An earlier solution I've used was to pass an array defining the form's configuration to the form type's constructor method and build these form fields during the buildForm method.

I don't know how you've set up your users so there will be some blanks that you need to fill in.

As a start I think this would happen in the controller but a better way would be to move as much logic to a Form Handler like the FOS User Bundle does: https://github.com/FriendsOfSymfony/FOSUserBundle/blob/master/Form/Handler/RegistrationFormHandler.php

You will need to get all of your user profile fields and prepare them in an array ready to be added to the form type constructor (see example for ProfileType).

$form_config = array(
    'fields' => array()
);

// get all user_profile_field entities add them to $form_config['fields']
// foreach $user_profile_fields as $user_profile_field...
// $form_config['fields'][] = $user_profile_field;

Then you need to create an array representation of your User based on the user_profile_data you've collected. This data is then bound to the form later on.

I'm not sure if you can pass this array version straight to the form. If the form is expecting an Entity you may need to pass the base user entity to the form first then bind the array version (containing the dynamic data) afterwards to set the dynamic field values.

Here's the Profile form class that you'll use:

class ProfileType extends AbstractType
{
    // stores the forms configuration
    // preferably map defaults here or in a getDefaultConfig method
    private $formConfig = array();

    // new constructor method to accept a form configuration
    public function __construct($form_config = array())
    {
        // merge the incoming config with the defaults
        // set the merged array to $this->formConfig
        $this->formConfig = $form_config;
    }

    public function buildForm(FormBuilder $builder, array $options)
    {
        // add any compulsory member fields here 
        // $builder->add( ... );

        // iterate over the form fields that were passed to the constructor
        // assuming that fields are an array of user_profile_field entities
        foreach ($this->formConfig['fields'] as $field) {
            // as form is not a straight entity form we need to set this
            // otherwise validation might have problems
            $options = array('property_path' => false);
            // if its a choice fields add some extra settings to the $options

            $builder->add($field->getField(), $field->getCategory(), $options);
        }

    }

This covers the output of the form.

In the controller create the form.

$profileForm = $this->createForm(new ProfileType($form_config), $user);

In summary the controller method should be structured something like this (filling in the blanks):

// get the user
// get user data
// create array version of user with its data as a copy

// get profile fields
// add them to the form config
// create form and pass form config to constructor and the user entity to createForm
// bind the array version of user data to form to fill in dynamic field's values


// check if form is valid
// do what is needed to set the posted form data to the user's data
// update user and redirect

I do feel that the Form Events are probably a better Symfony2 approach but this may hopefully help you get started. Then you can consider Form Events during the refactoring phase.

这篇关于Symfony2动态表单生成的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆