【问题标题】:Symfony2 Custom Form Type or ExtensionSymfony2 自定义表单类型或扩展
【发布时间】:2014-06-06 10:08:27
【问题描述】:

存在具有属性 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 来更新值?

【问题讨论】:

    标签: forms symfony autocomplete


    【解决方案1】:

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

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

    更新:

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

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

    【讨论】:

    • 所以对于价格和代码,我会添加 $builder->add('price', array('mapped' => false));到 OrderType,但是如果他们正在编辑订单,我将如何使用 FormEvents::PRE_SET_DATA 来填充价格和代码?
    • 添加 mapped false 取决于您的基础实体。如果您不希望将其保存到数据库中,那么它应该是false。关于编辑期间价格和代码的动态填充,您需要在表单中使用 POST_SUBMIT 事件。食谱链接有一个类似的例子。这是锚点:symfony.com/doc/current/cookbook/form/…
    • 我查看了 Sport POST_SUBMIT 示例,但没有看到如何在我的示例中使用它,我已使用新代码更新了问题。
    • 谢谢你的作品,这是最好的方法吗?
    • 这是建议的方式,因为它可以重复使用。这将防止在您的表单中“出现”额外的表单字段(SymfonyForm 组件禁止。)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多