To work properly, this plugin creates many elements in the dom, having their selector prefixed by default by
collection
. But if you need to display several collections in the same page (in the same form
or not), you will need to change this prefix so a click on "add" button will add the element to the right
collection.
Note that if you are using a form theme and used to write add buttons having collection-add
class,
plugin will in fact seek for <prefix>-add
. So if you change the prefix, you'll need to adapt
everywhere needed.
Contact information:
Locations:Chamberry, Olden Norway, Annecy
Hobbies:Sightseeing, Skiing, Eating mountain food
Other useful information:
Code used:
<script type="text/javascript"> $('.collection-cities').collection({ /* same selector as declared in TravelType */ allow_up: false, allow_down: false, prefix: 'city', /* will use city-add instead of collection-add for add button, etc) */ }); $('.collection-hobbies').collection({ /* same selector as declared in TravelType */ allow_up: false, allow_down: false, prefix: 'hobby', /* will use hobby-add instead of collection-add for add button, etc) */ }); </script>
<?php
namespace Fuz\AppBundle\Controller\Advanced;
use Fuz\AppBundle\Base\BaseController;
use Fuz\AppBundle\Entity\Advanced\FormWithSeveralCollections\City;
use Fuz\AppBundle\Entity\Advanced\FormWithSeveralCollections\Hobby;
use Fuz\AppBundle\Entity\Advanced\FormWithSeveralCollections\Travel;
use Fuz\AppBundle\Form\Advanced\FormWithSeveralCollections\TravelType;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;
use Symfony\Component\HttpFoundation\Request;
class FormWithSeveralCollectionsController extends BaseController
{
/**
* Advanced usage
*
* You can reference your form collection in the view, instead of
* putting a selector in the form type.
*
* @Route("/form-with-several-collections", name="formWithSeveralCollections")
* @Template()
*/
public function indexAction(Request $request)
{
$travel = new Travel();
$city = new City();
$city->setName('Chamberry');
$travel->getCities()->add($city);
$city = new City();
$city->setName('Olden Norway');
$travel->getCities()->add($city);
$city = new City();
$city->setName('Annecy');
$travel->getCities()->add($city);
$hobby = new Hobby();
$hobby->setType('Sightseeing');
$travel->getHobbies()->add($hobby);
$hobby = new Hobby();
$hobby->setType('Skiing');
$travel->getHobbies()->add($hobby);
$hobby = new Hobby();
$hobby->setType('Eating mountain food');
$travel->getHobbies()->add($hobby);
$form = $this->createForm(TravelType::class, $travel);
if ($request->isMethod('POST')) {
$form->handleRequest($request);
}
return [
'form' => $form->createView(),
'data' => $travel,
];
}
}
<?php
namespace Fuz\AppBundle\Entity\Advanced\FormWithSeveralCollections;
class City
{
private $name;
/**
* @return string
*/
public function getName()
{
return $this->name;
}
/**
* @param string $name
*/
public function setName($name)
{
$this->name = $name;
}
}
<?php
namespace Fuz\AppBundle\Entity\Advanced\FormWithSeveralCollections;
class Hobby
{
private $type;
/**
* @return string
*/
public function getType()
{
return $this->type;
}
/**
* @param string $type
*/
public function setType($type)
{
$this->type = $type;
}
}
<?php
namespace Fuz\AppBundle\Entity\Advanced\FormWithSeveralCollections;
use Doctrine\Common\Collections\ArrayCollection;
class Travel
{
protected $contact;
protected $cities;
protected $hobbies;
protected $comments;
public function __construct()
{
$this->cities = new ArrayCollection();
$this->hobbies = new ArrayCollection();
}
/**
* @return mixed
*/
public function getContact()
{
return $this->contact;
}
/**
* @param mixed $contact
*/
public function setContact($contact)
{
$this->contact = $contact;
}
/**
* @return ArrayCollection
*/
public function getCities()
{
return $this->cities;
}
/**
* @return ArrayCollection
*/
public function getHobbies()
{
return $this->hobbies;
}
/**
* @return string
*/
public function getComments()
{
return $this->comments;
}
/**
* @param string $comments
*/
public function setComments($comments)
{
$this->comments = $comments;
}
}
<?php
namespace Fuz\AppBundle\Form\Advanced\FormWithSeveralCollections;
use Fuz\AppBundle\Entity\Advanced\FormWithSeveralCollections\City;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
class CityType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('name', TextType::class, [
'label' => false,
]);
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults([
'data_class' => City::class,
]);
}
public function getBlockPrefix()
{
return 'city';
}
}
<?php
namespace Fuz\AppBundle\Form\Advanced\FormWithSeveralCollections;
use Fuz\AppBundle\Entity\Advanced\FormWithSeveralCollections\Hobby;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
class HobbyType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('type', TextType::class, [
'label' => false,
]);
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults([
'data_class' => Hobby::class,
]);
}
public function getBlockPrefix()
{
return 'hobby';
}
}
<?php
namespace Fuz\AppBundle\Form\Advanced\FormWithSeveralCollections;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\CollectionType;
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
use Symfony\Component\Form\Extension\Core\Type\TextareaType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
class TravelType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('contact', TextType::class, [
'label' => 'Your contact information',
]);
$builder->add('cities', CollectionType::class, [
'label' => 'Regions or cities you wish to visit',
'entry_type' => CityType::class,
'entry_options' => [
'label' => false,
],
'allow_add' => true,
'allow_delete' => true,
'prototype' => true,
'required' => false,
'by_reference' => true,
'delete_empty' => true,
'attr' => [
// Here is the selector for "cities" collection
'class' => 'collection-cities',
],
]);
$builder->add('hobbies', CollectionType::class, [
'label' => 'Activities you wish to do during this trip',
'entry_type' => HobbyType::class,
'entry_options' => [
'label' => false,
],
'allow_add' => true,
'allow_delete' => true,
'prototype' => true,
'required' => false,
'by_reference' => true,
'delete_empty' => true,
'attr' => [
// Here is the selector for "hobbies" collection
'class' => 'collection-hobbies',
],
]);
$builder->add('comments', TextareaType::class, [
'label' => 'Any comments?',
'required' => false,
]);
$builder->add('save', SubmitType::class, [
'label' => 'Send my request',
]);
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults([
'data_class' => 'Fuz\AppBundle\Entity\Advanced\FormWithSeveralCollections\Travel',
]);
}
public function getBlockPrefix()
{
return 'travel';
}
}
{% block city_widget %}
<div class="row">
<div class="col-md-10">
{{ form_widget(form) }}
</div>
<div class="col-md-2">
{# Note that "city" on classes below are the same as on "prefix" option #}
<a href="#" class="city-remove btn btn-default" title="Delete location"><span class="glyphicon glyphicon-trash"></span></a>
<a href="#" class="city-add btn btn-default" title="Add location"><span class="glyphicon glyphicon-plus-sign"></span></a>
</div>
</div>
{% endblock %}
{% block hobby_widget %}
<div class="row">
<div class="col-md-10">
{{ form_widget(form) }}
</div>
<div class="col-md-2">
{# Note that "hobby" on classes below are the same as on "prefix" option #}
<a href="#" class="hobby-remove btn btn-default" title="Delete hobby"><span class="glyphicon glyphicon-trash"></span></a>
<a href="#" class="hobby-add btn btn-default" title="Add hobby"><span class="glyphicon glyphicon-plus-sign"></span></a>
</div>
</div>
{% endblock %}
{% extends 'FuzAppBundle::layout.html.twig' %}
{% block extra_js %}
<script src="{{ asset('js/jquery.collection.js') }}"></script>
{% endblock %}
{% block title %}Form or page having several collections{% endblock %}
{% block body %}
<h2>{{ block('title') }}</h2>
<p>
To work properly, this plugin creates many elements in the dom, having their selector prefixed by default by
<code>collection</code>. But if you need to display several collections in the same page (in the same form
or not), you will need to change this prefix so a click on "add" button will add the element to the right
collection.
</p>
<p>
Note that if you are using a form theme and used to write add buttons having <code>collection-add</code> class,
plugin will in fact seek for <code><prefix>-add</code>. So if you change the prefix, you'll need to adapt
everywhere needed.
</p>
<hr/>
{%
form_theme form
'jquery.collection.html.twig'
'FuzAppBundle:Advanced/FormWithSeveralCollections:form-theme.html.twig'
%}
{{ form(form) }}
<hr/>
<div class="well">
<p><strong>Contact information</strong>: {{ data.contact }}</p>
<p>
<strong>Locations</strong>:
{% for key, city in data.cities %}{{ key > 0 ? ', ' : '' }}{{ city.name }}{% endfor %}
</p>
<p>
<strong>Hobbies</strong>:
{% for key, hobby in data.hobbies %}{{ key > 0 ? ', ' : '' }}{{ hobby.type }}{% endfor %}
</p>
<p><strong>Other useful information</strong>: {{ data.comments|nl2br }}</p>
</div>
<hr/>
<p>Code used:</p>
<pre>{{ block('script')|e }}</pre>
{{
tabs([
'Controller/Advanced/FormWithSeveralCollectionsController.php',
'Entity/Advanced/FormWithSeveralCollections/Travel.php',
'Entity/Advanced/FormWithSeveralCollections/City.php',
'Entity/Advanced/FormWithSeveralCollections/Hobby.php',
'Form/Advanced/FormWithSeveralCollections/TravelType.php',
'Form/Advanced/FormWithSeveralCollections/CityType.php',
'Form/Advanced/FormWithSeveralCollections/HobbyType.php',
'Resources/views/Advanced/FormWithSeveralCollections/index.html.twig',
'Resources/views/Advanced/FormWithSeveralCollections/form-theme.html.twig',
])
}}
{% endblock %}
{% block script %}
<script type="text/javascript">
$('.collection-cities').collection({ /* same selector as declared in TravelType */
allow_up: false,
allow_down: false,
prefix: 'city', /* will use city-add instead of collection-add for add button, etc) */
});
$('.collection-hobbies').collection({ /* same selector as declared in TravelType */
allow_up: false,
allow_down: false,
prefix: 'hobby', /* will use hobby-add instead of collection-add for add button, etc) */
});
</script>
{% endblock %}