Javascript Symfony-呈现形式(带原型)
我对symfony表单的原型存在图形问题。 我的CompetencyGroupe实体可以有许多CompetencyItem实体对象。 一切都很好,但渲染并不完美 在我的表单中创建新的CompetencyGroupe时,我可以添加和删除CompetencyItems子表单。 competenceItem表单有一个文本输入、一个选择输入和一个红色的删除按钮,由javascript生成 我尝试对齐这三个元素,但删除按钮总是位于其他两个元素下 我希望在视图中呈现的内容: 我现在拥有的是: 在我的Google Chrome开发工具中,我可以看到带有btn danger类的delete按钮与带有Capability\u groupe\u Capability\u items\u 0类的原型中的其他两个元素不在同一个div中: 我给您提供了我的原型视图\u item\u prototype.html.twig的代码Javascript Symfony-呈现形式(带原型),javascript,symfony,Javascript,Symfony,我对symfony表单的原型存在图形问题。 我的CompetencyGroupe实体可以有许多CompetencyItem实体对象。 一切都很好,但渲染并不完美 在我的表单中创建新的CompetencyGroupe时,我可以添加和删除CompetencyItems子表单。 competenceItem表单有一个文本输入、一个选择输入和一个红色的删除按钮,由javascript生成 我尝试对齐这三个元素,但删除按钮总是位于其他两个元素下 我希望在视图中呈现的内容: 我现在拥有的是: 在我的Goog
{% block competence_item_widget %}
<div id="{{ form.vars.id }}" class="row">
<div class="col-md-7">
{{ form_label(form.libelle, "Libelle", {'label_attr': {'class': 'sr-only control-label'}}) }}
{{ form_errors(form.libelle) }}
{{ form_widget(form.libelle, {'attr': {'class': 'form-control', 'placeholder': 'Libellé'}}) }}
</div>
<div class="col-md-3">
{{ form_label(form.niveau, "Niveau", {'label_attr': {'class': 'sr-only control-label'}}) }}
{{ form_errors(form.niveau) }}
{{ form_widget(form.niveau, {'attr': {'class': 'form-control selectModal'}}) }}
</div>
</div>
{% endblock %}
以及我的主要视图,其中包含CompetenceGroupe表单和Javascript代码,用于在每个原型表单上生成删除按钮:
{% form_theme formAddCompetence 'espaceUtilisateur/forms/prototypes/competence_item_prototype.html.twig' %}
{{ 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">
<h4><span class="label label-default">Les champs marqués d'un astérisque sont obligatoires.</span></h4>
{{ form_row(formAddCompetence.titre) }}
{{ form_row(formAddCompetence.competence_items) }}
{{ 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>
</form>
<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) {
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>'); // OLD
var $deleteLink = $('<div class="col-md-1"><button class="btn btn-danger"><i class="fa fa-trash-o"></i></button></div>');
// Ajout du lien
$prototype.last().append($deleteLink); // OLD
// 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>
谢谢任何人能抽出时间来帮助我。你能不能不把它附加到.row
function addDeleteLink($prototype) {
// Création du lien
//var $deleteLink = $('<div><a href="#" class="btn btn-danger">Supprimero</a></div>'); // OLD
var $deleteLink = $('<div class="col-md-1"><button class="btn btn-danger"><i class="fa fa-trash-o"></i></button></div>');
// Ajout du lien
$prototype.find('.row').append($deleteLink); // OLD
// 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;
});
}