2017-07-09 2 views
-1

状況:エンティティCompetenceGroupe(属性「titre」と「competence_items」)とエンティティ「CompetenceItem」(属性「libelle」と「niveau」)があります。 CompetenceGroupは複数のCompetenceItemを持つことができるので、コレクションです。symfony:カスタムプロトタイプを使ったコレクションのレンダリング

私は自分のプロトタイプを作成してコレクションのレンダリングをカスタマイズしました。それはうまくいっていますが、子供のCompetenceItemがフォームに表示されないため、既存のCompetenceGroupeを編集するときに問題があります。

私は自分のコードを表示します。

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">&times;</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のレンダリングが欠落していることです。たぶん私はそれらをレンダリングするためにそれをループする必要があります...あなたが見ることができるように、私は失われています...

あなたのアドバイスに事前に感謝!

答えて

1

本当に間違っているように見えるので、誰かがあなたの問題を解決するのに手間をかけて時間を費やすとは思わないでしょう。プロトタイプを自分で作成する代わりにform themeを使用する必要があります。 CompetenceGroupeType.phpで

1)、次の方法を追加します。またformによってitemを交換

{% block competence_group_widget %} 

    <div class="form-group"> 
     (...) 
    </div> 

{% endblock %} 

public function getBlockPrefix() 
{ 
    return 'competence_group'; 
} 

2)でcompetence_item_prototype.html.twigのコードを包みます。以下を追加し、{{ form_start(formAddCompetence, {...} }) }}関数を呼び出す前に、あなたのビューで

3)、:

{% form_theme formAddCompetence 'espaceUtilisateur/forms/prototypes/competence_item_prototype.html.twig' %} 

そして、私が作成したプラグインのスパムのビットが、右の目的のために:)あなたはに見ることができhttps://symfony-collection.fuz.orgには、フォームコレクションの作成方法に関する多くの例が記載されています。

+0

@ Alain Tiembloが応答に感謝します。あなたのexempleを使用していますが、CompetenceGroupeに既存のコンピテンシーアイテムがある場合、アイテムはまだありません。そのコードのどの部分が小枝のビューに表示されますか? – Thomas

+1

'{{form_row(formAddCompetence.ompetence_items)}}' –

+0

と同じですが、間違った場所にこれを追加している可能性があります...コードの一部 'code'

'code'はまだ私のものですCompetenceGroupフォーム。私はそれを削除する必要がありますか? – Thomas

関連する問題