在 Symfony 中嵌入表单集合 在 Bootstrap 中"Variable "扩展" does not exist"



目前我试图遵循symfony页面中的示例:

http://symfony.com/doc/current/cookbook/form/form_collections.html

但是对于我自己的页面。事情没有太大变化,而不是任务和标签,我有一个问题和选择(情况是,我想呈现一个表格,允许我创建一个不同的答案的问题,这样我们就可以玩"多项选择题考试")

为了做到这一点,我创建了实体Pregunta(问题)和实体选择。由于一个问题可以有多个选项,但这些选项只对应于一个问题,因此关系被映射为多对一。

下面是每个实体代码。(至少头部和映射信息)

namespace AoshidostudyBundleEntity;
use DoctrineCommonCollectionsArrayCollection;
use SymfonyComponentValidatorConstraints as Assert;
use DoctrineORMMapping as ORM;
/**
* Pregunta
*
* @ORMTable()
* @ORMEntity
*/
class Pregunta {
/**
 * @var integer
 *
 * @ORMColumn(name="id", type="integer")
 * @ORMId
 * @ORMGeneratedValue(strategy="AUTO")
 */
private $id;
/**
 * @var string
 *
 * @ORMColumn(name="Contenido", type="text")
 */
private $contenido;
/**
 * @var boolean
 *
 * @ORMColumn(name="Vof", type="boolean")
 */
private $vof;
/**
 * @var string
 *
 * @ORMColumn(name="Respuesta", type="text",options={"default":""})
 */
private $respuesta;
/**
 * @var boolean
 *
 * @ORMColumn(name="activo", type="boolean",options={"default":"TRUE"})
 */
private $activo;
/**
 * @ORMManyToMany(targetEntity="Tema", inversedBy="preguntas")
 * @ORMJoinTable(name="Preguntas_Temas")
 **/
private $temas;
/**
 * @AssertType(type="AoshidostudyBundleEntityChoice")
 * @AssertValid()
 * @ORMOneToMany(targetEntity="Choice", mappedBy="pregunta",cascade={"persist"})
 */
private $choices;
public function __construct() {
    $this->temas = new ArrayCollection();
    $this->choices = new ArrayCollection();
}

这是选择.php

namespace AoshidostudyBundleEntity;
use DoctrineORMMapping as ORM;
/**
* Choice
*
* @ORMTable()
* @ORMEntity
*/
class Choice
{
/**
 * @var integer
 *
 * @ORMColumn(name="id", type="integer")
 * @ORMId
 * @ORMGeneratedValue(strategy="AUTO")
 */
private $id;
/**
 * @var string
 *
 * @ORMColumn(name="contenido", type="string", length=1000)
 */
private $contenido;
/**
 * @var boolean
 *
 * @ORMColumn(name="correcto", type="boolean")
 */
private $correcto;
/**
 * @var boolean
 *
 * @ORMColumn(name="activo", type="boolean")
 */
private $activo;
/**
 * @ORMManyToOne(targetEntity="Pregunta", inversedBy="choices")
 * @ORMJoinColumn(name="idPregunta", referencedColumnName="id")
 */
protected $pregunta;

现在,根据示例,在嵌入表单时,您需要创建一个类型(用于问题),并在该类型中为另一个实体创建一个类型(用于选择)。所以我做到了

<?php
namespace AoshidostudyBundleform;
use AoshidostudyBundleformChoiceType;
use SymfonyComponentFormAbstractType;
use SymfonyComponentFormFormBuilderInterface;
use SymfonyComponentOptionsResolverOptionsResolverInterface;
class PreguntaType extends AbstractType {
public function buildForm(FormBuilderInterface $builder, array $options) {
    $builder->add('contenido');
    $builder->add('vof');
    $builder->add('respuesta');
    $builder->add('choices', 'collection', array(
        'type' => new ChoiceType(),
    ));
}
public function setDefaultOptions(OptionsResolverInterface $resolver) {
    $resolver->setDefaults(array(
        'data_class' => 'AoshidostudyBundleEntityPregunta',
    ));
}
public function getName() {
    return 'pregunta';
}
}

<?php
namespace AoshidostudyBundleForm;
use SymfonyComponentFormAbstractType;
use SymfonyComponentFormFormBuilderInterface;
use SymfonyComponentOptionsResolverOptionsResolverInterface;
class ChoiceType extends AbstractType {
public function buildForm(FormBuilderInterface $builder, array $options) {
    $builder->add('contenido');
}
public function setDefaultOptions(OptionsResolverInterface $resolver) {
    $resolver->setDefaults(array(
        'data_class' => 'AoshidostudyBundleEntityChoice',
    ));
}
public function getName() {
    return 'choice';
}
}

之后,如果我按照示例,添加 2 个选项,渲染它们,在那之前一切似乎都很好。

当我想使用原型等动态添加选项时,问题就来了。我做的第一件事是在preguntas类型上添加"allow_add => true"

 $builder->add('choices', 'collection', array(
        'type' => new ChoiceType(),
        'allow_add' => true,
    ));

之后,我只是复制并调整了 Javascript 代码以允许它添加多个选项,但此后每次我尝试刷新页面时都会收到此错误

变量"expanded"在BraincraftedBootstrapBundle:Form:bootstrap.html.twig中不存在在第173行

这是我的树枝

{% extends "AoshidostudyBundle:ABM:abmPreguntas.html.twig" %}
{% block form %}
<div class="panel panel-info">
    <div class="panel-heading">Agregar preguntas</div>
    <div class="panel-body">
        <div class="form-group">
            {{ form_start(form) }}
            {{ form_row(form.contenido) }}
            {{ form_row(form.respuesta) }}
            <ul class="choice" data-prototype="{{ form_widget(form.choices.vars.prototype)|e }}">
                {% for choice in form.choices %}
                    <li>
                        {{ form_row(choice) }}
                    </li>
                {% endfor %}
            </ul>
            <a href="#" id="add-another-choice">Add another choice</a>
            {{ form_end(form) }}
        </div>
    </div>
</div>
<script type="text/javascript">
    var $collectionHolder;
    // setup an "add a tag" link
    var $addTagLink = $('<a href="#" class="add_tag_link">Add a tag</a>');
    var $newLinkLi = $('<li></li>').append($addTagLink);
    jQuery(document).ready(function () {
        // Get the ul that holds the collection of tags
        $collectionHolder = $('ul.choice');
        // add the "add a tag" anchor and li to the tags ul
        $collectionHolder.append($newLinkLi);
        // count the current form inputs we have (e.g. 2), use that as the new
        // index when inserting a new item (e.g. 2)
        $collectionHolder.data('index', $collectionHolder.find(':input').length);
        $addTagLink.on('click', function (e) {
            // prevent the link from creating a "#" on the URL
            e.preventDefault();
            // add a new tag form (see next code block)
            addTagForm($collectionHolder, $newLinkLi);
        });
    });
    function addTagForm($collectionHolder, $newLinkLi) {
        // Get the data-prototype explained earlier
        var prototype = $collectionHolder.data('prototype');
        // get the new index
        var index = $collectionHolder.data('index');
        // Replace '__name__' in the prototype's HTML to
        // instead be a number based on how many items we have
        var newForm = prototype.replace(/__name__/g, index);
        // increase the index with one for the next item
        $collectionHolder.data('index', index + 1);
        // Display the form in the page in an li, before the "Add a tag" link li
        var $newFormLi = $('<li></li>').append(newForm);
        $newLinkLi.before($newFormLi);
    }
</script>
{%endblock%}

和控制器的位

        $pregunta = new Pregunta();
    $form = $this->createForm(new PreguntaType(), $pregunta, array(
        'action' => $this->generateUrl('preguntas_ABM'),
        'method' => 'POST',
    ));
return $this->render('AoshidostudyBundle:ABM:newForm.html.twig', array(
                'form' => $form->createView(),
                'paginas' => $pagination,
                'cantidad' => $cant,
    ));

我正在使用

  • Symfony 2.3.1
  • PHP 5.3.3

我会添加评论,但我的声誉还不够。您是否检查了文档以获取正确的Symfony版本?您链接到当前的Symfony文档(截至2.6),但您使用的是2.3.1版本。

尝试升级到最新版本,然后发现相同的错误。

另外,我看到你正在使用BraincraftedBootstrapBundle。这些文档适用于原版 Symfony 安装。你检查过他们的文件吗?

http://bootstrap.braincrafted.com/playground/forms.html#inlinesub

这看起来像你想要实现的目标。他们页面中的一个小代码片段,用于使用内联表单动态添加项目:

$this->createFormBuilder(array())
->add('repcol', 'bootstrap_collection', array(
    'type'               => 'repeated',
    'allow_add'          => true,
    'allow_delete'       => true,
    'sub_widget_col'     => 9,
    'button_col'         => 3,
    'prototype_name'     => 'inlinep',
    'options'            => array(
        'type' => 'text',
        'attr' => array('style' => 'inline')
    )
))
->getForm();

最新更新