我有3个人:(简历,DomaineCompetence和Competences) CV可以有很多DomaineCompetence,而DomaineCompetence可以有很多Competences,每个实体都有一个formType。
Cv实体
class Cv
{
//...
/**
* @OneToMany(targetEntity="DomaineCompetenceCv", mappedBy="cv", cascade={"persist"})
*
*/
private $domainesCompetence;
DomaineCompetence Entity
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,
))
;
}
DomaineCompetenceCvForm
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的Twig
<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的形式
有人可以帮我吗?谢谢大家。
<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;
});
}
});
答案 0 :(得分:2)
我在我的本地环境中重现了你的问题,同样的堆栈(Symfony 2.8.20)
从截图中我可以看到DomainesCompetence表单显示在Cv表单中,因为您创建了用于处理此集合的js。但是你确定实际的js处理每个 DomaineCompetence 表单中的能力集合吗?
也许你需要customize your CompetenceCvType collection prototype。请提供反馈。
**编辑:脏解决方案(工作但需要重构!!!)**
首先,在渲染Cv表单模板时填充DomaineCompetence(嵌入在Cv表单中)表单原型,但是未在DomaineCompetence表单中填充嵌入的Competence表单原型。您可以在控制器中填充二级表单集合,如下所示:
<?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;
});
}
});