【问题标题】:How to create 3 levels form with data-prototypes symfony 2.8如何使用数据原型 symfony 2.8 创建 3 个级别的表单
【发布时间】:2017-05-05 09:47:04
【问题描述】:

我有 3 个实体:(CV、DomaineCompetence 和 Competences) CV 可以有多个 DomaineCompetence,DomaineCompetence 可以有多个 Competence,每个实体都有一个 formType。

简历实体

class Cv
{ 
 //...

  /**
   * @OneToMany(targetEntity="DomaineCompetenceCv", mappedBy="cv", cascade={"persist"})
   * 
   */
   private $domainesCompetence;

领域能力实体

class DomaineCompetenceCv
{
 /**
  * @var int
  *
  * @ORM\Column(name="id", type="integer")
  * @ORM\Id
  * @ORM\GeneratedValue(strategy="AUTO")
  */
private $id;

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

/**
 * @ORM\ManyToOne(targetEntity="Cv", inversedBy="domainesCompetence")
 * @ORM\JoinColumn(name="cv_id", referencedColumnName="id")
 */
private $cv;

/**
 * @ORM\OneToMany(targetEntity="CompetenceCv", mappedBy="domaineCompetence", cascade={"persist"})
 * 
 */
private $competences;

CompetenceCv

class CompetenceCv
{
/**
 * @var int
 *
 * @ORM\Column(name="id", type="integer")
 * @ORM\Id
 * @ORM\GeneratedValue(strategy="AUTO")
 */
private $id;

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

/**
 * @ORM\Column(name="niveau", type="integer")
 */
private $niveau;

/**
 * @ORM\ManyToOne(targetEntity="DomaineCompetenceCv", inversedBy="competences")
 * @ORM\JoinColumn(name="domaine_id", referencedColumnName="id")
 */
private $domaineCompetence;

CVForm

 public function buildForm(FormBuilderInterface $builder, array $options)
{ $builder
    //...
    ->add('domainesCompetence', CollectionType::class, array(

        'entry_type' => DomaineCompetenceCvForm::class,
        'allow_add'    => true,
        'by_reference' => false,


    ))      
        ;

}

领域能力CvForm

public function buildForm(FormBuilderInterface $builder, array $options)
{
    $builder->add('nom')
            ->add('competences', CollectionType::class, array(

        'entry_type' => CompetenceCvForm::class,
        'allow_add'    => true,
        'by_reference' => true,


    ))      
            ;
}

CompetencesCvForm

 public function buildForm(FormBuilderInterface $builder, array $options)
{
    $builder->add('nom')->add('niveau')    ;
}

用于 Cv 的树枝

 <form role="form" action="" {{ form_enctype(form) }} method="POST">
                             {{ form_widget(form._token) }}  
    //...
     <h4 class="no-margin-top has-divider text-highlight">Compétences</h4>
             <div id="domaineCV" class="domaineCV" data-prototype="{{ form_widget(form.domainesCompetence.vars.prototype)|e('html_attr') }}">

                 {% for com in form.domainesCompetence %}

                   <div class="" data-prototype="{{ form_widget(com.vars.prototype)|e('html_attr') }}">

                   </div>
                   {% endfor %}
               </div>
   </form>     

我使用javaScript添加了超过DomaineCompetence但问题是Competence的形式不显示

有人可以帮助我吗?谢谢大家。

领域能力的 JS

<script type="text/javascript">
 $(document).ready(function() {

var $container = $('div#domaineCV');


var $addLink = $('<a href="#" id="add_category" class="btn btn-default">Ajouter une Domaine de compétence</a>');
$container.append($addLink);


$addLink.click(function(e) {
  addCategory($container);
  e.preventDefault(); // évite qu'un # apparaisse dans l'URL
  return false;
});


var index = $container.find(':input').length;


if (index == 0) {
  addCategory($container);
} else {

  $container.children('div').each(function() {
    addDeleteLink($(this));
  });
}


function addCategory($container) {

  var $prototype = $($container.attr('data-prototype').replace(/__name__label__/g, 'Catégorie n°' + (index+1))
      .replace(/__name__/g, index));


  addDeleteLink($prototype);


  $container.append($prototype);

  index++;
}


function addDeleteLink($prototype) {

  $deleteLink = $('<a href="#" class="btn btn-danger">Supprimer</a>');


  $prototype.append($deleteLink);


  $deleteLink.click(function(e) {
    $prototype.remove();
    e.preventDefault(); =
    return false;
  });
}

});

【问题讨论】:

    标签: forms symfony symfony-2.8


    【解决方案1】:

    我在本地环境中重现了您的问题,相同的堆栈 (Symfony 2.8.20)

    从您的屏幕截图中,我可以看到 DomainesCompetence 表单显示在 Cv 表单中,因为您创建了用于处理此集合的 js。但是您确定实际的 js 会处理每个 DomaineCompetence 表单中的 competences 集合吗?

    也许你需要customize your CompetenceCvType collection prototype。请提供反馈。

    ** 编辑:肮脏的解决方案(工作但需要重构!!!)**

    第一点,DomaineCompetence(嵌入在您的 Cv 表单中)表单原型在您呈现 Cv 表单模板时填充,但嵌入的 Competence 表单原型未填充到您的 DomaineCompetence 表单中。您可以像这样在控制器中填充二级表单集合:

    <?php
    
    namespace AppBundle\Controller;
    
    use AppBundle\Form\CvType;
    use AppBundle\Form\DomaineCompetenceCvType;
    use AppBundle\Form\CompetenceCvType;
    use Symfony\Bundle\FrameworkBundle\Controller\Controller;
    use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
    
    class CvController extends Controller
    {
        /**
         * @Route("/new")
         */
         public function newAction()
         {
             $form = $this->createForm(CvType::class);
             $domaineCompetenceCvForm = $this
                 ->createForm(
                     CompetenceCvType::class,
                     null,
                     array('auto_initialize' => false
                 )
             );
             $form->get('domainesCompetence')
                 ->add($domaineCompetenceCvForm)
             ;
    
    
             return $this->render(
                 ':cv:new.html.twig',
                 array(
                     'form' => $form->createView(),
                 )
             );
        }
    }
    

    接下来像这样更新您的模板:

    {% extends 'base.html.twig' %}
    
    {% form_theme form _self %}
    
    {% block _appbundle_cv_domainesCompetence_entry_widget %}
        {{ form_row(form.nom) }}
    {% endblock %}
    
    {% block title %}AppBundle:Cv:new{% endblock %}
    
    {% block body %}
        <h1>Welcome to the Cv:new page</h1>
    
        <form role="form" action="" {{ form_enctype(form) }} method="POST">
            {{ form_widget(form._token) }}  
    
            <h4 class="no-margin-top has-divider text-highlight">Compétences</h4>
            Domaines
            <div style="border: 1px solid green" id="domaineCV" class="domaineCVs" data-prototype="{{ form_widget(form.domainesCompetence.vars.prototype)|e('html_attr') }}">
    
                <div style="border: 1px solid yellow" id="competencesProto" data-prototype="{{ form_widget(form.children.domainesCompetence)|e('html_attr') }}">
                </div>
            </div>
    
    
        </form> 
    {% endblock %}
    {% block javascripts %}
        {{ parent() }} {# load your jquery and bootstrap deps #}
        <script type="text/javascript">
            {# custom js handling your collections here #}
        </script>
    
    {% endblock %}
    

    那么这就是js:

    $(document).ready(function() {
    
        var $prototype = '';
        var $container = $('div#domaineCV');
        var $competencesContainer = '';
        var $competencesProtoContainer = $('div#competencesProto');
    
        var $addLink = $('<a href="#" id="add_category" class="btn btn-success">Ajouter une Catégorie</a>');
        var $addCompetence = $('<a href="#" id="add_competence" class="btn btn-warning">Ajouter une compétence</a>');
        $container.after($addLink);
    
    
        $addLink.click(function(e) {
            addCategory($container);
            e.preventDefault(); // évite qu'un # apparaisse dans l'URL
            return false;
        });
    
        $addCompetence.click(function(e) {
            addCompetence($competencesContainer);
            e.preventDefault(); // évite qu'un # apparaisse dans l'URL
            return false;
        });
    
    
        var index = $container.find(':input').length;
        var competencesIndex = 0;
    
        if (index == 0) {
            addCategory($container);
            competencesIndex = $competencesContainer.find(':input').length; 
        } else {
            $container.children('div').each(function() {
              addDeleteLink($(this));
            });
        }
    
        function addCategory($container) {
    
            $prototype = $($container.attr('data-prototype').replace(/__name__label__/g, 'Catégorie n°' + (index+1))
                .replace(/__name__/g, index));
            $container.prepend($prototype);
             $competencesContainer = $('div#competencesProto');
            $competencesContainer.after($addCompetence);   
    
            addCompetence($competencesContainer);
    
            addDeleteLink($prototype);
    
            index++;
        }
    
        function addCompetence($competencesContainer) {
            var $competenceProto = $($competencesProtoContainer.attr('data-prototype').replace(/__name__label__/g, 'Catégorie n°' + (competencesIndex+1))
              .replace(/__name__/g, competencesIndex));
    
          $competencesContainer.append($competenceProto);
          $prototype.append($competenceProto);
      
          addCompetenceDeleteLink($competenceProto);
    
          competencesIndex++;
        }
    
        function addDeleteLink($element) {
            $deleteLink = $('<a href="#" class="btn btn-danger">Supprimer catégorie</a>');
    
            $element.append($deleteLink);
    
    
            $deleteLink.click(function(e) {
                $element.remove();
                e.preventDefault(); 
                return false;
            });
        }
    
        function addCompetenceDeleteLink($element) {
    
            $deleteCompetenceLink = $('<a href="#" class="btn btn-danger">Supprimer competence</a>');
    
            $element.append($deleteCompetenceLink);
    
    
            $deleteCompetenceLink.click(function(e) {
              $element.remove();
              e.preventDefault(); 
              return false;
            });
        }
    
    });

    【讨论】:

    • 感谢您的回答,DomainesCompetence 表单仅显示 name(nom),但未显示此域中的 Competences 集合
    • 这就是我要说的。检查您的 js 是否也处理 Competences 的集合。也许 js 处理了一些使用 DomainesCompetence 表单的 CSS 类,但没有处理 Competences 集合中使用的 CSS 类。我可以看看你的 js 来完全重现你的问题吗?
    • 我编辑问题以添加我的脚本 js ,我也认为问题出在脚本 js 中。但我从 2 周开始遇到同样的问题,我找不到解决方案:(
    • 有人可以帮帮我吗?我试图为我的结束研究项目开发一个应用程序,但我真的被阻止了:( .. 非常感谢
    • @DhiaEddineFarah 我用一个可行的解决方案更新了我的帖子。这应该可以解决问题,但很脏。也许你应该尝试为这个问题做另一个应用程序设计。
    猜你喜欢
    • 2017-03-22
    • 2016-03-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-11-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多