【问题标题】:Setting a Quiz System设置测验系统
【发布时间】:2016-08-02 21:41:02
【问题描述】:

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

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

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

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

但是我在浏览器中得到了空的选择输入。请提出这方面的完美解决方案?

注意:

我注意到如果我添加

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

对于我的 QuestionType,我在 new.html.twig 中得到一个空选择的表单

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

 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;

...
}

选择类型:

class ChoiceType extends AbstractType
{
    /**
     * @param FormBuilderInterface $builder
     * @param array $options
     */
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('answer')
            ->add('correct')

        ;
    }
    
    /**
     * @param OptionsResolver $resolver
     */
    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults(array(
            'data_class' => 'ChallengeBundle\Entity\Choice'
        ));
    }
} 

【问题讨论】:

  • 我有一个草稿系统。如果您对此感兴趣,请告诉我
  • 为什么不使用Moodle,这方面最好的和最常用的平台?见amazing stats
  • 使用 TextType 而不是 ChoiceType。你在正确的轨道上。
  • ChoiceType 是 Choice 实体的形式,谢谢 Jonny
  • 当我添加 use Symfony\Component\Form\Extension\Core\Type\ChoiceType;对于我的问题类型,当我删除此导入时,我得到一个空选择的表单,因此它将调用选择实体的表单我收到此错误:第 38 行的 form_div_layout.html.twig 中不存在变量“扩展”,但我没有t 在我的实体中有任何变量称为“扩展”

标签: javascript php symfony twig


【解决方案1】:

1- 如果您的目标只是在 ChoiceFormType 中选择现有的答案,则必须在 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 不变。

然后在你的树枝模板中,当你呈现你的选择表单时,你可以像这样调用你的答案集合:

<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 所说,您必须在 data-prototype 属性中添加一些 javascript 来读取 html,并在单击“添加新答案”链接时动态添加新的答案表单。

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

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

【讨论】:

  • 感谢您的回答我尝试了您的建议,但我也得到一个空选择我正在尝试添加新答案
  • 当我添加 use Symfony\Component\Form\Extension\Core\Type\ChoiceType;对于我的问题类型,当我删除此导入时,我得到一个空选择的表单,因此它将调用选择实体的表单我收到此错误:第 38 行的 form_div_layout.html.twig 中不存在变量“扩展”,但我没有t 在我的实体中有任何变量称为“扩展”
  • 所以是正常的。此解决方案生成空输入(而不是选择)以添加新答案。如果您想选择现有答案,则必须使用我的第一点。
  • 但如果数据库中存储了大量答案,这不是一个好主意。用户将首先创建许多答案,然后创建一个新问题并在答案之间进行选择
【解决方案2】:

有一个很好的包用于管理 symfony 嵌入式表单和原型。您不需要编写手头的 js 代码,并且有很多选择。签到here

希望对您有所帮助。

【讨论】:

    【解决方案3】:

    您需要按照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);
        });
    });
    

    【讨论】:

    • 我添加了文档中描述的 Js 代码 看看图片有'添加标签' 感谢您的回答
    【解决方案4】:

    谢谢大家的帮助

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-11-11
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多