我有3个实体,Product,ProductOption和ProductImage。
产品是一对多的ProductOption和ProductOption是一对多的ProductImage。
在我的ProductType中,我有一个用于entry_type ProductOptionType的CollectionType。 在我的ProductOptionType中,我有一个用于entry_type ProductImageType的CollectionType。
所以我在这里有多个嵌入式集合,我不知道如何在视图中显示表单ProductImageType。现在我有这个:
// {{ form.start(form) }}
// {{ form.errors(form) }}
// other form fields
{{ form.label(form.product_option, "Options") }}
{{ form.errors(form.product_option) }}
{{ form.widget(form.product_option) }}
<a href="#" id="add_options">Add options</a>
// Some javascript to handle add_options
这是ProductType:
class ProductType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('name', TextType::class)
->add('description', TextareaType::class)
->add('price', MoneyType::class)
->add('category', EntityType::class, array(
'class' => 'AppBundle:ProductCategory',
'choice_label' => 'code',
))
->add('genre', EntityType::class, array(
'class' => 'AppBundle:ProductGenre',
'choice_label' => 'code',
))
->add('product_option', CollectionType::class, array(
'entry_type' => ProductOptionType::class,
'allow_add' => true,
'allow_delete' => true,
'by_reference' => false,
))
->add('save', SubmitType::class)
;
}
/**
* {@inheritdoc}
*/
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'data_class' => Product::class,
));
}
/**
* {@inheritdoc}
*/
public function getBlockPrefix()
{
return 'appbundle_product';
}
}
ProductOptionType:
class ProductOptionType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('product_size', EntityType::class, array(
'class' => 'AppBundle:ProductSize',
'choice_label' => 'code',
))
->add('product_color', EntityType::class, array(
'class' => 'AppBundle:ProductColor',
'choice_label' => 'code',
))
->add('quantity', IntegerType::class)
->add('enabled', CheckboxType::class)
->add('images', CollectionType::class, array(
'entry_type' => ProductImageType::class,
'allow_add' => true,
'allow_delete' => true,
'required' => false,
'by_reference' => false,
))
->add('print_zones', ChoiceType::class, array(
'choices' => array(
'Face' => 'face',
'Dos' => 'dos',
'Manche droite' => 'manche_droite',
'Manche gauche' => 'manche_gauche',
),
'multiple' => true,
'expanded' => true,
))
;
}
/**
* {@inheritdoc}
*/
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'data_class' => ProductOption::class,
));
}
/**
* {@inheritdoc}
*/
public function getBlockPrefix()
{
return 'appbundle_product_option';
}
}
ProductImageType:
class ProductImageType extends AbstractType
{
/**
* {@inheritdoc}
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('imageFile', VichImageType::class, array(
'label' => "Sélectionnez une image",
))
;
}
/**
* {@inheritdoc}
*/
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'data_class' => ProductImage::class,
));
}
/**
* {@inheritdoc}
*/
public function getBlockPrefix()
{
return 'appbundle_product_image';
}
}
我的form.html.twig
{{ form_start(form) }}
{{ form_errors(form) }}
<div class="form-group">
{{ form_label(form.name, "Nom") }}
{{ form_errors(form.name) }}
{{ form_widget(form.name, {'attr': {'class': 'form-control'}}) }}
</div>
<div class="form-group">
{{ form_label(form.description, "Description") }}
{{ form_errors(form.description) }}
{{ form_widget(form.description) }}
</div>
<div class="form-group">
{{ form_label(form.price, "Prix") }}
{{ form_errors(form.price) }}
{{ form_widget(form.price) }}
</div>
<div class="form-group">
{{ form_label(form.category, "Catégorie") }}
{{ form_errors(form.category) }}
{{ form_widget(form.category) }}
</div>
<div class="form-group">
{{ form_label(form.genre, "Sexe") }}
{{ form_errors(form.genre) }}
{{ form_widget(form.genre) }}
</div>
<div class="form-group">
{{ form_label(form.product_option, "Ajoutez une ou plusieurs variantes") }}
{{ form_errors(form.product_option) }}
{{ form_widget(form.product_option) }}
<a href="#" id="add_variante" class="btn btn-default">Ajouter une variante</a>
</div>
<div class="text-center">
{{ form_widget(form.save, {'attr': {'class': 'btn btn-primary'}}) }}
</div>
{{ form_rest(form) }}
{{ form_end(form) }}
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script type="text/javascript">
$(document).ready(function() {
var $container = $('div#appbundle_product_product_option');
var index = $container.find(':input').length;
$('#add_variante').click(function(e) {
addVariante($container);
e.preventDefault(); // évite qu'un # apparaisse dans l'URL
return false;
});
if (index == 0) {
addVariante($container);
} else {
if(!document.getElementsByClassName('form-checkbox')){
$container.children('div').each(function() {
addDeleteLink($(this));
});
}
}
function addVariante($container) {
var template = $container.attr('data-prototype')
.replace(/__name__label__/g, 'Variante n°' + (index+1))
.replace(/__name__/g, index)
;
var $prototype = $(template);
addDeleteLink($prototype);
$container.append($prototype);
index++;
}
function addDeleteLink($prototype) {
var $deleteLink = $('<a href="#" class="btn btn-danger">Supprimer</a>');
$prototype.append($deleteLink);
$deleteLink.click(function(e) {
$prototype.remove();
e.preventDefault();
return false;
});
}
});
感谢您的帮助。