设置测验系统

时间:2016-08-02 10:23:23

标签: javascript php symfony twig

我正在开发一个基于MCQ的测验系统,我的目标是帮助教师在同一页面上为该问题添加新的问题和选择。根据Symfony文档,我可以嵌入Collection of Forms,所以我尝试将ChoiceType嵌入到问题表单中:

(Comparator<T> & Serializable)

new.html.twig页面代码(新问题):

->add('answers', CollectionType::class, array(
    'entry_type'   => ChoiceType::class,
    'allow_add'    => true,
));
        ;  

但我在浏览器中输入空选择输入。请在这方面建议什么是完美的解决方案?

enter image description here

注意:

我注意到如果我添加

<label> Choose answers : </label>
<ul class="tags" data-prototype="{{form_widget(form.answers.vars.prototype)|e('html_attr') }}">
</ul>

到我的QuestionType我在new.html.twig

中得到一个空选择的表单

当我删除此导入时,如果我打开new.html.twig,我会收到此错误:

use Symfony\Component\Form\Extension\Core\Type\ChoiceType; 

但我的实体中没有任何名为'expanded'的变量

选择实体

 Variable "expanded" does not exist in form_div_layout.html.twig at line 38

问题实体:

class Choice
{
    ...

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

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


    /**
     * @var
     * @ORM\ManyToOne(targetEntity="ChallengeBundle\Entity\Question",inversedBy="answers")
     */
    private $question;

...
}

选择类型:

class Question
{
    ...

    /**
     * @var
     * @ORM\OneToMany(targetEntity="ChallengeBundle\Entity\Choice",mappedBy="question",cascade={"remove"})
     */
    private $answers;

...
}

4 个答案:

答案 0 :(得分:1)

1 - 如果您的目标只是选择表单中的现有答案,则必须在ChoiceFormType中使用EntityTypeField而不是CollectionTypeField

->add('answers', EntityType::class, array(
    // query choices from this entity
    'class' => 'YourBundle:Question',

    // use the Question.name property as the visible option string
    'choice_label' => 'name',

   // used to render a select box, check boxes or radios
   // 'multiple' => true,
   // 'expanded' => true,
)); 

2 - 但是,如果您想在“选择”表单中添加新答案,则必须保留CollectionTypeField

然后在渲染您的选择表单时,在您的twig模板中,您可以像这样调用您的答案集合:

<ul class="answers" data-prototype="{{ form_widget(form.answers.vars.prototype)|e('html_attr') }}">
     {% for answer in form.answers %}
          <li>{{ form_row(answer.answer) }}</li>
          <li>{{ form_row(answer.correct) }}</li>
     {% endfor %}
</ul>

这将显示第一个输入空

最后,正如documentation所说,你必须添加一些javascript来读取data-prototype属性中的html,并在点击&#34;添加新答案时动态添加新的答案表格。链接。

  

Doc示例(您只需根据您的情况进行调整):

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.tags');

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

答案 1 :(得分:1)

有一个很好的捆绑管理symfony嵌入式表单和原型。您不需要手头编写js代码并且有很多选项。签入here

希望这对你有所帮助。

答案 2 :(得分:0)

您需要按照documentation section Allowing "new" Tags with the "Prototype"

中的说明添加JavaScript

摘自文档:

  

实现这一切所需的实际代码可能会有很大差异,但这里有一个例子:

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

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.tags');

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

答案 3 :(得分:0)

谢谢大家的帮助

我通过创建另一个实体来解决我的问题似乎symfony框架在我的表单ChoiceTypeSymfony\Component\Form\Extension\Core\Type\ChoiceType

的名称中找到了混淆