Symfony2自定义表单类型或扩展名

时间:2014-06-06 10:08:28

标签: forms symfony autocomplete

存在包含属性Product的实体订单。

表单已创建OrderType,允许将产品添加到订单。

这很有效,但不是很有趣。

而不是显示简单的产品下拉列表,它应该是自动完成功能。

但是,在选择自动填充值时,应使用有关产品的信息填充一些附加字段。

从自动填充中选择产品时,应使用价格和代码填充另外两个字段。

已经创建了返回数据的控制器方法,并且jquery可以使用一些方便的自动完成功能。

我知道如何直接将解决方案破解到表单模板中,但我想制作一个可重用的组件。

问题是如何使用此行为创建自定义表单或扩展名?

class Order {
    /**
     * @ORM\Id
     * @ORM\Column(type="integer")
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    protected $id;

    /**
     * @ORM\ManyToOne(targetEntity="Product", inversedBy="orders", cascade={"persist"})
     * @ORM\JoinColumn(name="product_id", referencedColumnName="id")
     */
    protected $product;  

    protected $quantity;
}

class Product {

    /**
     * @ORM\Id
     * @ORM\Column(type="integer")
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    protected $id;

    /**
     * @ORM\OneToMany(targetEntity="Product", mappedBy="product")
     */
    protected $orders;

    protected $name;
    protected $price;
    protected $code;
}

class OrderType extends AbstractType {

    public function buildForm(FormBuilderInterface $builder, array $options) {
        $builder
            ->add('quantity')
            ->add('product');    
    }
}

更新 我已使用以下内容更新OrderType:

    $builder
        ->add('ppprice', 'text', array('mapped' => false, 'data' => 2));

    $builder->addEventListener(
        FormEvents::PRE_SET_DATA, function (FormEvent $event) use($builder) {
        $form = $event->getForm();
        $order = $event->getData();
        $builder
            ->add('ppprice', 'text', array('mapped' => false, 'data' => 21));
        $builder
            ->add('test', 'text', array('mapped' => false, 'data' => 21));
    }
    );

正在调用PRE_SET_DATA,但从未添加新的表单字段测试,并且不会使用新值更新ppprice。

如何让PRE_SET_DATA更新值?

1 个答案:

答案 0 :(得分:1)

您应该在表单上附加处理FormEvent事件的POST_SUBMIT。 这里有一个完整示例(包括jquery ajax行为)的教程:
http://symfony.com/doc/current/cookbook/form/dynamic_form_modification.html

这将负责为您的FormType添加动态字段。如果您希望稍后重复使用,可以创建EventListener,也可以在构建自定义表单类型时通过Closures附加事件。

<强> 更新

首先尝试使用以下代码查看并检查PRE_SET_DATA事件是否正常启动。请注意,您无法将$builder注入此Closure。 (您可以但不会工作)只需使用$form中的->add对象和Closure字段,就像这样:

$builder->addEventListener(
        FormEvents::PRE_SET_DATA, function (FormEvent $event) {
        $form = $event->getForm();
        $order = $event->getData();

        $form->add('ppprice', 'text', array('mapped' => false, 'data' => 21));
        $form->add('test', 'text', array('mapped' => false, 'data' => 21));
    }
    );