Collection de Collections
Bonjour !
Je bloque sur un problème de `CollectionType`. J'ai un formulaire qui sert à créer des membres de famille. Chaque membre de famille peut avoir un certain nombre d'adresses et un certain nombre de moyens de contact. J'ai donc deux `CollectionType` dans un `CollectionType`.
Mon formulaire de départ :
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('childsFamily', CollectionType::class, array(
'entry_type' => RelationshipType::class,
'allow_add' => true,
'prototype' => true,
'attr' => array('class' => 'child-family')
));
}
public function getBlockPrefix()
{
return 'AddChildStep3';
} |
Dont le RelationshipType ressemble à ceci :
Code:
1 2 3 4 5 6 7 8 9 10 11 12
| public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('relRole', EntityType::class, array(
'class' => 'VSCrmBundle:RelRole'
))
//->add('sourceId', PersonChildType::class)
->add('destinationId', PersonRelationshipType::class, array(
'block_name' => 'destination_id',
'label' => 'Responsible'
));
} |
Et la le destinationId qui est un PersonRelationshipType qui est :
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('firstName')
->add('lastName')
->add('bornOn', BirthdayType::class, array(
'required' => false
))
->add('familySituation', ChoiceType::class, array(
'choices' => array(
'Single' => 'SINGLE',
'Married' => 'MARRIED',
'Other' => 'OTHER'
)
))
->add('profession')
->add('addresses', CollectionType::class, array(
'entry_type' => AddressType::class,
'allow_add' => true,
'allow_delete' => true
))
->add('medias', CollectionType::class, array(
'entry_type' => MediaType::class,
'allow_add' => true,
'allow_delete' => true
));
} |
Chaque membre de famille est ajouté grâce à une fonction jQuery qui nous vient tout droit de la documentation :
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65
| var familyCollectionHolder;
// Set up an "add address" link
var addFMemberLink = $('<a href="#" class="add_fmember_link">Add family member</a>');
var newFamilyLinkP = $('<p class="centered"></p>').append(addFMemberLink);
function addFmemberForm(familyCollectionHolder, newFamilyLinkP){
// Get the data prototype
var prototype = familyCollectionHolder.data('prototype');
// get the new index
var index = familyCollectionHolder.data('index');
// Replace '__name__' in the prototype's HTML
//instead be a number based on how many items we have
var newForm = prototype.replace(/__name__/g, index);
// Increase the index with one for the new item
familyCollectionHolder.data('index', index+1);
//Display the form in the page nan li, before the "add address" link
var newFormP = $('<div class="one-fmember"></div>').append(newForm);
newFamilyLinkP.before(newFormP);
addFMemberDeleteLink(newFormP);
}
function addFMemberDeleteLink(fmemberFormP)
{
var removeFormP = $('<p class="centered"><a href="#" style="color:red">Delete member</a></p>');
fmemberFormP.append(removeFormP);
removeFormP.on('click', function(e){
e.preventDefault();
fmemberFormP.remove();
})
}
function handleFcData(familyCollectionHolder,newFamilyLinkP)
{
// Get the div that holds the collection of addresses
familyCollectionHolder = $('div#familyMembersList');
// add a delete link to all of the existensing forms
familyCollectionHolder.find('div.one-fmember').each(function(){
addFMemberDeleteLink($(this));
});
// add the "add address" anchor
familyCollectionHolder.append(newFamilyLinkP);
// Count the current form inputs
// use that as the new index when inserting a new item
familyCollectionHolder.data('index', familyCollectionHolder.find(':input').length);
return familyCollectionHolder;
}
jQuery(document).ready(function(){
familyCollectionHolder = handleFcData(familyCollectionHolder, newFamilyLinkP);
addFMemberLink.on('click',function(e)
{
// Prevent the link from creating a "#" on the URL
e.preventDefault();
// add a new address form
addFmemberForm(familyCollectionHolder, newFamilyLinkP);
})
}); |
J'ai donc un code HTML de la sorte :
Code:
1 2 3 4 5 6 7 8
| <div class="row">
<p class="centered spaced">Define child's family</p>
</div>
<div class="row">
<div id="familyMembersList" data-prototype="{{ form_widget(form.childsFamily.vars.prototype)|e('html_attr') }}">
</div>
</div> |
J'ai fait un `entry_widget` customisé qui fait en sorte à ce que à chaque fois qu'un membre de famille est ajouté, je met ça parfaitement en forme et j'ajoute mes deux autres collections :
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102
| {% block _AddChildStep3_childsFamily_entry_widget %}
<div class="row">
<div class="form-group{% if (not compound or force_error|default(false)) and not valid %} has-error{% endif %}">
<div class="col-lg-4 col-md-4 col-sm-6 col-xs-12">
{{- form_label(form.relRole, "", {'label_attr': {'class': 'pull-right'}}) -}}
</div>
<div class="col-lg-4 col-md-4 col-sm-6 col-xs-12">
{{- form_widget(form.relRole) -}}
</div>
<div class="col-lg-4 col-md-4 col-sm-6 col-xs-12">
{{- form_errors(form.relRole) -}}
</div>
</div>
<br/>
<div class="form-group{% if (not compound or force_error|default(false)) and not valid %} has-error{% endif %}">
<div class="col-lg-4 col-md-4 col-sm-6 col-xs-12">
{{- form_label(form.destinationId.firstName, "", {'label_attr': {'class': 'pull-right'}}) -}}
</div>
<div class="col-lg-4 col-md-4 col-sm-6 col-xs-12">
{{- form_widget(form.destinationId.firstName) -}}
</div>
<div class="col-lg-4 col-md-4 col-sm-6 col-xs-12">
{{- form_errors(form.destinationId.firstName) -}}
</div>
</div>
<br/>
<div class="form-group{% if (not compound or force_error|default(false)) and not valid %} has-error{% endif %}">
<div class="col-lg-4 col-md-4 col-sm-6 col-xs-12">
{{- form_label(form.destinationId.lastName, "", {'label_attr': {'class': 'pull-right'}}) -}}
</div>
<div class="col-lg-4 col-md-4 col-sm-6 col-xs-12">
{{- form_widget(form.destinationId.lastName) -}}
</div>
<div class="col-lg-4 col-md-4 col-sm-6 col-xs-12">
{{- form_errors(form.destinationId.lastName) -}}
</div>
</div>
<br/>
<div class="form-group{% if (not compound or force_error|default(false)) and not valid %} has-error{% endif %}">
<div class="col-lg-4 col-md-4 col-sm-6 col-xs-12">
{{- form_label(form.destinationId.bornOn, "", {'label_attr': {'class': 'pull-right'}}) -}}
</div>
<div class="col-lg-4 col-md-4 col-sm-6 col-xs-12">
{{- form_widget(form.destinationId.bornOn) -}}
</div>
<div class="col-lg-4 col-md-4 col-sm-6 col-xs-12">
{{- form_errors(form.destinationId.bornOn) -}}
</div>
</div>
<br/>
<div class="form-group{% if (not compound or force_error|default(false)) and not valid %} has-error{% endif %}">
<div class="col-lg-4 col-md-4 col-sm-6 col-xs-12">
{{- form_label(form.destinationId.profession, "", {'label_attr': {'class': 'pull-right'}}) -}}
</div>
<div class="col-lg-4 col-md-4 col-sm-6 col-xs-12">
{{- form_widget(form.destinationId.profession) -}}
</div>
<div class="col-lg-4 col-md-4 col-sm-6 col-xs-12">
{{- form_errors(form.destinationId.profession) -}}
</div>
</div>
<br/>
<div class="row">
<p class="centered">Adresses</p>
<div id="addressList" data-prototype="{{ form_widget(form.destinationId.addresses.vars.prototype)|e('html_attr') }}">
</div>
</div>
<br/>
<div class="row">
<p class="centered">Medias</p>
<div id="mediasList" data-prototype="{{ form_widget(form.destinationId.medias.vars.prototype)|e('html_attr') }}">
</div>
</div>
</div>
<br/>
{% endblock %} |
Mon grand problème est d'ajouter les adresses et les moyens de contact pour chaque membre de famille en jQuery (car je suis nul en front en partie)... Je dois faire un Frankenstein à partir du code jQuery d'ajout de membre de famille + ajout d'une adresse + ajout d'un moyen de contact et je n'y arrive pas. Quelqu'un a une idée de comment résoudre ça ?
On a donc le code d'ajout d'adresse (standart)
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69
|
var collectionHolder;
// Set up an "add address" link
var addAddressLink = $('<a href="#" class="add_address_link">Add address</a>');
var newLinkP = $('<p class="centered"></p>').append(addAddressLink);
function addAddressForm(collectionHolder, newLinkP){
// Get the data prototype
var prototype = collectionHolder.data('prototype');
// get the new index
var index = collectionHolder.data('index');
// Replace '__name__' in the prototype's HTML
//instead be a number based on how many items we have
var newForm = prototype.replace(/__name__/g, index);
// Increase the index with one for the new item
collectionHolder.data('index', index+1);
//Display the form in the page nan li, before the "add address" link
var newFormP = $('<div class="one-address"></div>').append(newForm);
newLinkP.before(newFormP);
addAddressDeleteLink(newFormP);
}
function addAddressDeleteLink(AddressFormP)
{
var removeForm = $('<p class="centered"><a href="#" style="color:red">Delete Address</a></p>');
AddressFormP.append(removeForm);
removeForm.on('click', function(e){
e.preventDefault();
AddressFormP.remove();
});
}
function handleAcData(collectionHolder,newLinkP)
{
// Get the div that holds the collection of addresses
collectionHolder = $('div#addressList');
// add the "add address" anchor
collectionHolder.append(newLinkP);
// add a delete link to all of the existing media form elements
collectionHolder.find('div#one-address').each(function(){
addAddressDeleteLink($(this))
});
// Count the current form inputs
// use that as the new index when inserting a new item
collectionHolder.data('index', collectionHolder.find(':input').length);
return collectionHolder;
}
jQuery(document).ready(function(){
collectionHolder = handleAcData(collectionHolder, newLinkP);
addAddressLink.on('click', function(e)
{
// Prevent the link from creating a "#" on the URL
e.preventDefault();
// add a new address form
addAddressForm(collectionHolder, newLinkP);
})
}); |
et de moyen de contact :
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68
| var collectionHolder2;
// Set up an "add address" link
var addMediaLink = $('<a href="#" class="add_media_link">Add Contact mean</a>');
var newLinkP2 = $('<p class="centered"></p>').append(addMediaLink);
function addMediaForm(collectionHolder, newLinkP2){
// Get the data prototype
var prototype = collectionHolder.data('prototype');
// get the new index
var index = collectionHolder.data('index');
// Replace '__name__' in the prototype's HTML
//instead be a number based on how many items we have
var newForm = prototype.replace(/__name__/g, index);
// Increase the index with one for the new item
collectionHolder.data('index', index+1);
//Display the form in the page nan li, before the "add address" link
var newFormP = $('<div class="one-media"></div>').append(newForm);
newLinkP2.before(newFormP);
addMediaDeleteLink(newFormP);
}
function addMediaDeleteLink(mediaFormP)
{
var removeForm = $('<p class="centered"><a href="#" style="color:red">Delete Media</a></p>');
mediaFormP.append(removeForm);
removeForm.on('click', function(e){
e.preventDefault();
mediaFormP.remove();
});
}
function handleMcData(collectionHolder2,newLinkP2)
{
// Get the div that holds the collection of addresses
collectionHolder2 = $('div#mediasList');
// add the "add address" anchor
collectionHolder2.append(newLinkP2);
// add a delete link to all of the existing media form elements
collectionHolder2.find('div#one-media').each(function(){
addMediaDeleteLink($(this))
});
// Count the current form inputs
// use that as the new index when inserting a new item
collectionHolder2.data('index', collectionHolder2.find(':input').length);
return collectionHolder2;
}
jQuery(document).ready(function(){
collectionHolder2 = handleMcData(collectionHolder2, newLinkP2);
addMediaLink.on('click', function(e)
{
// Prevent the link from creating a "#" on the URL
e.preventDefault();
// add a new address form
addMediaForm(collectionHolder2, newLinkP2);
})
}); |
Le problème est que si je met juste les 3 fichiers dans mon code, les collectionHolder de l'adresse et des moyens de contact ne sont pas chargés au click sur `ajouter un membre de famille`. J'ai essayé de placer le code d'ajout d'adresse et de moyen de contact dans le code
Code:
1 2 3 4 5 6 7 8 9
| addFMemberLink.on('click',function(e)
{
// Prevent the link from creating a "#" on the URL
e.preventDefault();
// add a new address form
addFmemberForm(familyCollectionHolder, newFamilyLinkP);
}); |
Ca donne bien l'effet visuel mais l'index de l'adresse et du moyen de contact ne s'incrémente pas donc à la fin ca sauvegarde une adresse maximum et un moyen de contact maximum....
Merci pour votre aide !