情況:我有一個實體CompetenceGroupe(帶有屬性「titre」和「competence_items」)和一個實體「CompetenceItem」(帶有屬性「libelle」和「niveau」)。 CompetenceGroupe可以有多個CompetenceItem,所以它是一個集合。Symfony:使用自定義原型渲染集合
爲此,我創建了自己的原型來定製集合的渲染。它工作正常,但是當我想編輯現有的CompetenceGroupe時遇到問題,因爲兒童的CompetenceItem不在表單中呈現。
我告訴你我的代碼。
CompetenceGroupeType
class CompetenceGroupeType extends AbstractType
{
/**
* @param FormBuilderInterface $builder
* @param array $options
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('titre')
->add('competence_items', CollectionType::class, array(
'entry_type' => CompetenceItemType::class,
'allow_add' => true,
'allow_delete' => true,
'label' => false,
'prototype' => true,
))
//->add('save', SubmitType::class)
;
}
/**
* @param OptionsResolver $resolver
*/
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'AppBundle\Entity\CompetenceGroupe',
));
}
}
CompetenceItemType
class CompetenceItemType extends AbstractType
{
/**
* @param FormBuilderInterface $builder
* @param array $options
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('libelle')
->add('niveau', EntityType::class, array(
'class' => 'AppBundle:CompetenceNiveau',
'choice_label' => 'libelle_competence_niveau_fr',
'required' => false,
))
;
}
/**
* @param OptionsResolver $resolver
*/
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'AppBundle\Entity\CompetenceItem',
));
}
}
的形式CompetenceGroupe
{{ form_start(formAddCompetence, { 'attr': {'class': 'formCompetenceAdd'} }) }}
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
<h4 class="modal-title" id="myModalLabel">{{ libelleCategorie }}</h4>
</div>
<div class="modal-body">
{{ dump(formAddCompetence) }}
<h4><span class="label label-default">Les champs marqués d'un astérisque sont obligatoires.</span></h4>
{# render the task's only field: description #}
{{ form_row(formAddCompetence.titre) }}
<div id="competence_groupe_competence_items"
data-prototype="
{% filter escape %}
{{ include('espaceUtilisateur/forms/prototypes/competence_item_prototype.html.twig', { 'item': formAddCompetence.competence_items.vars.prototype }) }}
{% endfilter %}">
</div>
{{ form_widget(formAddCompetence._token) }}
<br>
<a href="#" id="add_category" class="btn btn-default">Ajouter une catégorie</a>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Annuler</button>
{% if objectCompetence.idCompetenceGroupe is not empty %}
{{ form_widget(formAddCompetence.edit) }}
<input type="hidden" name="idCompetenceGroupe" id="idCompetenceGroupe" value="{{ objectCompetence.idCompetenceGroupe }}">
{% else %}
{{ form_widget(formAddCompetence.save) }}
{% endif %}
</div>
<script type="text/javascript">
$(document).ready(function() {
// On récupère la balise <div> en question qui contient l'attribut « data-prototype » qui nous intéresse.
var $container = $('div#competence_groupe_competence_items');
// On définit un compteur unique pour nommer les champs qu'on va ajouter dynamiquement
var index = $container.find(':input').length;
// On ajoute un nouveau champ à chaque clic sur le lien d'ajout.
$('#add_category').click(function(e) {
addCategory($container);
e.preventDefault(); // évite qu'un # apparaisse dans l'URL
return false;
});
// On ajoute un premier champ automatiquement s'il n'en existe pas déjà un (cas d'une nouvelle annonce par exemple).
if (index == 0) {
//console.log('index');
addCategory($container);
} else {
// S'il existe déjà des catégories, on ajoute un lien de suppression pour chacune d'entre elles
$container.children('div').each(function() {
addDeleteLink($(this));
});
}
// La fonction qui ajoute un formulaire CategoryType
function addCategory($container) {
// Dans le contenu de l'attribut « data-prototype », on remplace :
// - le texte "__name__label__" qu'il contient par le label du champ
// - le texte "__name__" qu'il contient par le numéro du champ
var template = $container.attr('data-prototype')
.replace(/__name__label__/g, 'Catégorie n°' + (index+1))
.replace(/__name__/g, index)
;
// On crée un objet jquery qui contient ce template
var $prototype = $(template);
// On ajoute au prototype un lien pour pouvoir supprimer la catégorie
addDeleteLink($prototype);
// On ajoute le prototype modifié à la fin de la balise <div>
$container.append($prototype);
// Enfin, on incrémente le compteur pour que le prochain ajout se fasse avec un autre numéro
index++;
}
// La fonction qui ajoute un lien de suppression d'une catégorie
function addDeleteLink($prototype) {
// Création du lien
var $deleteLink = $('<div><a href="#" class="btn btn-danger">Supprimero</a></div>');
// Ajout du lien
$prototype.last().append($deleteLink);
// Ajout du listener sur le clic du lien pour effectivement supprimer la catégorie
$deleteLink.click(function(e) {
$prototype.remove();
e.preventDefault(); // évite qu'un # apparaisse dans l'URL
return false;
});
}
});
</script>
而且我自定義原型
<div class="form-group">
{{ form_label(item.libelle, "libelle a", {'label_attr': {'class': 'col-md-3 control-label'}}) }}
{{ form_errors(item.libelle) }}
<div>
{{ form_widget(item.libelle) }}
</div>
</div>
<div class="form-group">
{{ form_label(item.niveau, "niveau a", {'label_attr': {'class': 'col-md-3 control-label'}}) }}
{{ form_errors(item.niveau) }}
<div>
{{ form_widget(item.niveau) }}
</div>
</div>
也許我的問題是缺少CompetenceGroupe現有CompetenceItem的渲染。也許我必須循環它才能渲染它們...正如你所看到的,我迷失了...
在此先感謝您的建議!
@ Alain Tiemblo感謝您的回覆。我已經使用你的例子,但是當CompetenceGroupe擁有現有的能力項目時仍然沒有任何項目。什麼部分的代碼顯示他們在樹枝視圖? – Thomas
您應該使用'{{form_row(formAddCompetence.ompetence_items)}}' –
仍然是一樣的,也許我已經在錯誤的地方添加了這個...請注意,我的部分代碼'code'