symfony2:使用可自定义的表单字段生成扩展类别实体

时间:2013-07-25 14:55:21

标签: forms symfony entity

所以我正在尝试构建这个具有票务系统的应用程序。每个故障单实体都有一个类别。这一切都很好,但我想在填写新票时为每个类别设置单独的表单字段。另外,我想让它们可配置。这就是概念应该是这样的(例子):

Category1 form: Ticket Form + Amount + Starting Date

Category2 form: Ticket Form + Point of Contact (choice) + etc...

因此用户选择一个类别,表单将动态更改。我目前已经设置了每个类别是一个单独的实体,并且有一个表单监听器,它根据用户选择的内容添加适当类别的子表单。问题是所有这些都是硬编码的。我想有一些可以编辑/添加/删除类别及其表单字段的工具。例如,我想有一天向Category2添加“Amount”字段。

关于如何做到这一点我没有太多想法,没有为每个类别生成单独的实体。我想有一个名为TicketCategory的实体,其中包含Custom1,Custom2,Custom3等字段,它们代表了在某些配置文件中定义的不同表单字段。问题在于字段类型。我会有一个日期/数字/字符串/等的大混合...

有人对如何解决这个想法有任何建议吗?

1 个答案:

答案 0 :(得分:0)

我有一个申请,裁判可以报名参加不同的比赛。对于每场锦标赛,我需要提出一系列不同的问题。所以我将问题移到yaml文件中并添加了足够的信息,以便我可以动态创建表单元素。所以基本上我会:

# tourn.yml
tourns:

     opencup:
         desc:    "USSF Open Cup 2013 - Decatur, Alabama - April 12, 13, 14"

         plan:
             lodgingNights:
                     Fri:
                         type:      radio
                         label:     Lodging Friday Night
                         date:     '2013-04-12'
                         choices:  [No: No, Yes: Yes]
                         default:   No
                     Sat:
                         type:      radio
                         label:     Lodging Saturday Night
                         date:     '2013-04-13'
                         choices:  [No: No, Yes: Yes]
                         default:   No

             availabilityDays:
                     Fri:
                         type:      select
                         label:     Availability Friday
                         date:     '2013-04-12'
                         default:   None
                         choices:
                             None:     None
                             Evening:  Kickoff 5PM
                             Not Sure: Not Sure
                      etc

因此,计划数组最终被传递给计划子表单,而计划子表单又创建了所有单独的表单元素。然后我有一个计划实体,它只将所有单个选择存储在一个数组数据库列中。似乎工作正常。

=============================================== ========================

评论要求更多代码。这是我的“动态”PlanFormType“

class PlanFormType extends AbstractType
{
protected $metaData = null;

public function getName() { return 'cerad_tourn_person_plan'; }

public function setMetaData($data) { $this->metaData = $data; }
public function getMetaData(     ) { return $this->metaData; }

public function buildForm(FormBuilderInterface $builder, array $options)
{   
    $items = $this->getMetaData();

    foreach($items as $name => $item)
    {
        $isChoice = false;

        switch($item['type'])
        {
            case 'radio':
                $isChoice = true;
                $expanded = true;
                $multiple = false;
                $attr = array('class' => 'radio-medium');
                break;

            case 'select':
                $isChoice = true;
                $expanded = false;
                $multiple = false;
                $attr = array();
                break;

            case 'text':

                $attr = array();

                if (isset($item['size'])) $attr['size'] = $item['size'];

                $builder->add($name,'text',array(
                    'label'    => $item['label'],
                    'required' => false,
                    'attr'     => $attr,
                ));
                break;

        }
        if ($isChoice) 
        {
            $builder->add($name,'choice',array(
                'label'       => $item['label'],
                'required'    => false,
                'empty_value' => false,
                'choices'     => $item['choices'],
                'expanded'    => $expanded,
                'multiple'    => $multiple,
                'attr'        => $attr,
            ));
        }
    }
}
}