我正在开发一个基于MCQ的测验系统,我的目标是帮助教师在同一页面上为该问题添加新的问题和选择。根据Symfony文档,我可以嵌入Collection of Forms,所以我尝试将ChoiceType嵌入到问题表单中:
(Comparator<T> & Serializable)
new.html.twig页面代码(新问题):
->add('answers', CollectionType::class, array(
'entry_type' => ChoiceType::class,
'allow_add' => true,
));
;
但我在浏览器中输入空选择输入。请在这方面建议什么是完美的解决方案?
我注意到如果我添加
<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;
...
}
答案 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框架在我的表单ChoiceType
和Symfony\Component\Form\Extension\Core\Type\ChoiceType