symfony2表单构建器 - 如何混合表单数据和文本信息

时间:2013-06-24 20:35:08

标签: forms symfony

在销售数字商品的传统系统中......

产品按产品类别(4)组织。产品可能包括其他子产品。客户可以购买产品并成为产品实例的所有者。每个产品实例都有自己的配置。

的问题:

客户应该可以取消他们的产品实例。因此,我想建立一个如下的中央取消表格:

form

表单包含客户的所有产品实例。产品按类别组织。每个产品实例应该由描述其配置(属性+一些子实体属性)的短文本块来描述。在描述旁边应该有一个复选框。如果选中此框,则应取消产品实例。

实体字段类型(扩展,多个)似乎是一个不错的选择?但是如何在复选框旁边显示文字信息?

如何使用symfony2表单构建器实现这样的表单?

如果我可以访问自定义表单类型视图对象中的产品对象来构建输出就足够了

    <!-- how a product instance should be displayed -->
    <!-- description on the left -->
    <div class="left">
      {{ product.name }} {{ product.calcExpireDate() }}<br />
      {% for s in product.getSubentities() %} {{ s.name }}, {% endfor %}
    </div>
    <!-- checkbox on the right -->
    <div class="right">
      <input type="checkbox ..[] > <label>Cancel<label>
    </div>

2 个答案:

答案 0 :(得分:1)

以下是您的解决方案:

实体和表单类型最小化(没有getter / setter)

假设您有两个类别和产品类似于此的实体:

/**
 * @ORM\Table()
 * @ORM\Entity()
 */
class Category
{
    /**
     * @var integer
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

    /**
     * @var string
     * @ORM\Column(name="name", type="string")
     */
    private $name;

    /**
     * @var \Doctrine\Common\Collections\ArrayCollection
     * @ORM\OneToMany(targetEntity="Product", mappedBy="category")
     */
    private $products;

    public function __toString()
    {
        return $this->name;
    }
}

/**
 * @ORM\Table()
 * @ORM\Entity(repositoryClass="Acme\DemoBundle\Entity\ProductRepository")
 */
class Product
{
    /**
     * @var integer
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

    /**
     * @var string
     * @ORM\Column(name="name", type="string")
     */
    private $name;

    /**
     * @var string
     * @ORM\Column(name="description", type="text")
     */
    private $description;

    /**
     * @var Category
     * @ORM\ManyToOne(targetEntity="Category", inversedBy="products")
     */
     private $category;

     /**
      * @var boolean
      */
     private $cancel;

     /**
      * @var boolean
      */
     private $asap;
}

现在,创建产品取消的元模型:

class Cancel
{
    /**
     * @var string
     */
    private $name;

    /**
     * @var \Doctrine\Common\Collections\ArrayCollection
     */
    private $products;

    /**
     * Constructor
     */
    public function __construct()
    {
        $this->products = new \Doctrine\Common\Collections\ArrayCollection();
    }
}

注意:这不是实体(表),只是简单的'ol PHP对象。

为这些产品和类别生成CRUD,并使用以下buildForm方法为Cancel模型创建CancelType:

public function buildForm(FormBuilderInterface $builder, array $options)
{
    $builder->add('name');
    $builder->add('products', 'collection', array('type' => new ProductType()));
}

创建将呈现新的CancelType

的操作
public function cancelAction()
{
    $em = $this->getDoctrine()->getManager();
    $productsToCancel = $em->getRepository('AcmeDemoBundle:Product')->findAll();

    $cancel = new Cancel();
    foreach ($productsToCancel as $product) {
        $cancel->addProduct($product);
    }
    $form = $this->createForm(new CancelType(), $cancel);

    return $this->render('AcmeDemoBundle:Product:cancel.html.twig', array(
        'form' => $form->createView(),
    ));
}

并使用以下内容创建cancel.html.twig:

<div>
    {{ form_widget(form.name) }}
</div>

{% for product in form.products %}
    <fieldset>
        <legend>{{ product.vars.value.category.name }}</legend>
        <table>
            <tr>
                <td>{{ product.vars.value.name }}</td>
                <td>
                    {{ form_widget(product.cancel) }} cancel
                    {{ form_widget(product.asap) }} asap
                </td>
            </tr>
            <tr>
                <td>
                    {{ product.vars.value.description }}
                </td>
            </tr>
        </table>
    </fieldset>
{% endfor %}

通过标准的Symfony2表单验证,您可以获得所需的一切以及优势。

最后一件事是在控制器中添加动作以处理表单提交:)

答案 1 :(得分:0)

您应该在这种情况下使用表单集合。 symfony2 docs中的示例显示了如何执行此操作。