Advanced usage: example with Doctrine

That's not really an advanced topic, but the sample will be a bit hard to read (as it takes many files), so let's say it targets more experienced Symfony users.

In this demo, we're displaying a MyArray of MyElements, both persisted into the database. The MyArray entity only have an id and a name, and MyElement has id, MyArray's id and a value. This is quite the same as we seen in all demos, but persisted.


Existing arrays:
Name Open Delete
__________________________________________ Open Delete
. Open Delete
#72uuuu Open Delete
%3F Open Delete
<script>alert('test')</script> Open Delete
<script>alert('test')</script>%n%n%n%n%n%n Open Delete
<script>alert('test')</script>%n%n%n%n%n%n<script>alert('test')</script>%n%n%n%n%n%n<script>alert('test')</script>%n%n%n%n%n%n<script>alert('test')</script>%n%n%n%n%n%n<script>alert('test')</script>%n%n%n%n%n%n<script>alert('test')</script>%n%n%n%n%n%n<sc Open Delete
1 Open Delete
10 Open Delete
11 Open Delete
1111 Open Delete
11111111aaa Open Delete
1111Yapi Open Delete
121113 Open Delete
1aa Open Delete
2222 example Open Delete
2344234 Open Delete
3 Open Delete
32jnni Open Delete
7 Open Delete
8 Open Delete
86787 Open Delete
88 Open Delete
888 Open Delete
999 Open Delete
a2 Open Delete
aa Open Delete
aaa Open Delete
aaaa Open Delete
aaaaa Open Delete
aaamine Open Delete
aaamine22222 Open Delete
aarzarzample Open Delete
adfadf Open Delete
adsada Open Delete
arrayGilmry Open Delete
asas Open Delete
asd Open Delete
asdas Open Delete
asdasdadasd Open Delete
asdasdasd Open Delete
asdf Open Delete
asdfasdfasd8888 Open Delete
azerty Open Delete
b Open Delete
balala Open Delete
bam Open Delete
bbb Open Delete
bbbbbbbbbbb Open Delete
bdfdfdfdf Open Delete
bla Open Delete
blah Open Delete
caca Delete
caracas Open Delete
cccio Open Delete
checks Open Delete
Christos Open Delete
cx<wc Open Delete
d Open Delete
dasdsad Open Delete
Demo Open Delete
dfg Open Delete
dfvds Open Delete
dsadsadd Open Delete
dsds Open Delete
dsf Open Delete
dsfsdfs Open Delete
e Open Delete
ejemplo 2017-11-23 Open Delete
eqweqwe Open Delete
erwgfuıgj8hlı Open Delete
exadasdas Open Delete
exampldfdfe Open Delete
example Open Delete
example Radu Open Delete
example123 Open Delete
example22222222222222 Open Delete
example3243423 Open Delete
example4 Open Delete
exampleasd Open Delete
exampleasfsafasf Open Delete
exampled Open Delete
exampleeeeeeeeeeeee Open Delete
exampleRW2 Open Delete
examplesadasdsdsad Open Delete
exampless Open Delete
exampple Open Delete
examqdqsple Open Delete
Existing arrays: Open Delete
fasdfasf Open Delete
Fda Open Delete
fdg Open Delete
fdgfdgfdgfdgfd Open Delete
fdsfds Open Delete
ff d Open Delete
ffsss Open Delete
fg Open Delete
fgdfgfg Open Delete
fgfdgfdgdg Open Delete
fghjk, Open Delete
frfrf Open Delete
Fruits Open Delete
fsda Open Delete
fsdfsdf Open Delete
fsgv Open Delete
fuck you Open Delete
geht nicht Open Delete
ghk Open Delete
ghkjgykg Open Delete
Group B Open Delete
gtgt Open Delete
hbhbhb Open Delete
HEYY :D Open Delete
hgjgjh Open Delete
hh Open Delete
ho Open Delete
hoho Open Delete
ismail Open Delete
itemList2 Open Delete
j Open Delete
jb Open Delete
jhkl Open Delete
jj Open Delete
jk Open Delete
kaas Open Delete
kfhk Open Delete
kiki Open Delete
kjkjkj Open Delete
kjkk Open Delete
kkik Open Delete
klk Open Delete
klklklkl Open Delete
lel Open Delete
lj Open Delete
llllllllllllllll Open Delete
lmklk Open Delete
lolo Open Delete
mec Open Delete
moi Open Delete
mt Open Delete
Mumbojumbo Open Delete
mytest Open Delete
name Open Delete
Names Open Delete
nbnv Open Delete
New Array Open Delete
new_22 Open Delete
new%20test Open Delete
nmn Open Delete
Nouveau Open Delete
ñsfkjaldsa Open Delete
o Open Delete
oı Open Delete
oezjfez Open Delete
oij Open Delete
Open Delete
olaboga Open Delete
ordersCollection Open Delete
Ouiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii Open Delete
Ouiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii Open Delete
Ouiiiiiiiiiiiiiiiiiiiiiiiilul Open Delete
ouiou Open Delete
pablo Open Delete
pp Open Delete
pppppp Open Delete
prabu Open Delete
Putin Open Delete
qsdfqsdf Open Delete
question2 Open Delete
qwe Open Delete
qweqw Open Delete
qwerqwerqw Open Delete
qwery2 Open Delete
rerwrer Open Delete
rrrr Open Delete
rtr Open Delete
saassa Open Delete
sad.asdasd.sdsad Open Delete
sadsd Open Delete
sam Open Delete
sami Open Delete
sample Open Delete
samples Open Delete
sdf Open Delete
sdg Open Delete
sdsd Open Delete
sfdf Open Delete
sqsq Open Delete
Stringkey Open Delete
t11 Open Delete
Ta mere la grosse choin Open Delete
Ta mere la grosse tchoin Open Delete
Ta%20mere%20la%20grosse%20choin Open Delete
tableau cellule unique Open Delete
Telous Open Delete
terst Open Delete
tes Open Delete
tesr Open Delete
tesst Open Delete
test Open Delete
test34 Open Delete
Teste Open Delete
TESTEN Open Delete
Tester Open Delete
testN17 Open Delete
Teszt Open Delete
this is an array Open Delete
tojo Open Delete
try01 Open Delete
tset Open Delete
ttt Open Delete
tttttz Open Delete
tutu Open Delete
tyty Open Delete
tzzttz Open Delete
uhj Open Delete
ui Open Delete
uiu Open Delete
uu Open Delete
Vai que da Open Delete
Vai%20que%20da Open Delete
vcvcvcvcvv Open Delete
Volta%20Dilma%20Fora%20Temer Open Delete
Volta+Dilma+Fora+Temer Open Delete
vv Open Delete
werweexample Open Delete
why doctrine on delete not work Open Delete
Woop wooop Open Delete
wqeqe Open Delete
wqewqeqwewewq Open Delete
www Open Delete
wxc<wxc Open Delete
xxx Open Delete
yfcx Open Delete
yut Open Delete
yy Open Delete
☘ Cela fonctionne ☘ Open Delete
<?php

namespace Fuz\AppBundle\Base;

use Fuz\AppBundle\Entity\Value;
use Fuz\AppBundle\Form\ValueType;
use Fuz\QuickStartBundle\Base\BaseController as QuickStartBase;
use Symfony\Component\Form\Extension\Core\Type;
use Symfony\Component\HttpFoundation\Request;

class BaseController extends QuickStartBase
{
    protected function createContextSample(Request $request, $name = 'form', $values = ['a', 'b', 'c'])
    {
        $data = ['values' => $values];

        $form = $this
           ->get('form.factory')
           ->createNamedBuilder($name, Type\FormType::class, $data)
           ->add('values', Type\CollectionType::class, [
               'entry_type'    => Type\TextType::class,
               'label'         => 'Add, move, remove values and press Submit.',
               'entry_options' => [
                   'label' => 'Value',
               ],
               'allow_add'    => true,
               'allow_delete' => true,
               'prototype'    => true,
               'attr'         => [
                   'class' => "{$name}-collection",
               ],
           ])
           ->add('submit', Type\SubmitType::class)
           ->getForm()
        ;

        $form->handleRequest($request);
        if ($form->isValid()) {
            $data = $form->getData();
        }

        return [
            $name         => $form->createView(),
            "{$name}Data" => $data,
        ];
    }

    protected function createAdvancedContextSample(Request $request, $name = 'advancedForm')
    {
        $a = new Value('a');
        $b = new Value('b');
        $c = new Value('c');

        $data = ['values' => [$a, $b, $c]];

        $form = $this
           ->get('form.factory')
           ->createNamedBuilder($name, Type\FormType::class, $data)
           ->add('values', Type\CollectionType::class, [
               'entry_type'   => ValueType::class,
               'label'        => 'Add, move, remove values and press Submit.',
               'allow_add'    => true,
               'allow_delete' => true,
               'prototype'    => true,
               'required'     => false,
               'attr'         => [
                   'class' => "{$name}-collection",
               ],
           ])
           ->add('submit', Type\SubmitType::class)
           ->getForm()
        ;

        $form->handleRequest($request);
        if ($form->isValid()) {
            $data = $form->getData();
        }

        return [
            $name         => $form->createView(),
            "{$name}Data" => $data,
        ];
    }
}
<?php

namespace Fuz\AppBundle\Controller;

use Fuz\AppBundle\Base\BaseController;
use Fuz\AppBundle\Entity\Address;
use Fuz\AppBundle\Entity\Addresses;
use Fuz\AppBundle\Entity\Fancy;
use Fuz\AppBundle\Entity\FancyCollection;
use Fuz\AppBundle\Entity\Value;
use Fuz\AppBundle\Form\AddressesType;
use Fuz\AppBundle\Form\FancyCollectionType;
use Fuz\AppBundle\Form\MyArrayType;
use Fuz\AppBundle\Form\ValueType;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;
use Symfony\Component\Form\Extension\Core\Type;
use Symfony\Component\HttpFoundation\Request;

/**
 * @Route("/advanced")
 */
class AdvancedController extends BaseController
{
    /**
     * Advanced usage
     *
     * You can reference your form collection in the view, instead of
     * putting a selector in the form type.
     *
     * @Route("/mvcCompliance", name="mvcCompliance")
     * @Template()
     */
    public function mvcComplianceAction(Request $request)
    {
        $data = ['values' => ['a', 'b', 'c']];

        $form = $this
           ->createFormBuilder($data)
           ->add('values', Type\CollectionType::class, [
               'entry_type'    => Type\TextType::class,
               'label'         => 'Add, move, remove values and press Submit.',
               'entry_options' => [
                   'label' => 'Value',
               ],
               'allow_add'    => true,
               'allow_delete' => true,
               'prototype'    => true,
               'required'     => false,
//                   'attr' => array (
//                           'class' => 'my-selector', <--- Not MVC compliant!
//                   ),
           ])
           ->add('submit', Type\SubmitType::class)
           ->getForm()
        ;

        $form->handleRequest($request);
        if ($form->isValid()) {
            $data = $form->getData();
        }

        return [
            'form' => $form->createView(),
            'data' => $data,
        ];
    }

    /**
     * Advanced usage
     *
     * A custom form theme helps define button's layout and positions as and where you want.
     *
     * @Route("/customFormTheme", name="customFormTheme")
     * @Template()
     */
    public function customFormThemeAction(Request $request)
    {
        $data = ['values' => [new Value('a'), new Value('b'), new Value('c')]];

        $form = $this
           ->createFormBuilder($data)
           ->add('values', Type\CollectionType::class, [
               'entry_type'   => ValueType::class,
               'label'        => 'Add, move, remove values and press Submit.',
               'allow_add'    => true,
               'allow_delete' => true,
               'prototype'    => true,
               'required'     => false,
               'attr'         => [
                   'class' => 'collection',
               ],
           ])
           ->add('submit', Type\SubmitType::class)
           ->getForm()
        ;

        $form->handleRequest($request);
        if ($form->isValid()) {
            $data = $form->getData();
        }

        return [
            'form' => $form->createView(),
            'data' => $data,
        ];
    }

    /**
     * Advanced usage
     *
     * Same demo as above, but with the add button located at the bottom of
     * the form instead of close to each field.
     *
     * @Route("/customFormThemeAddBottom", name="customFormThemeAddBottom")
     * @Template()
     */
    public function customFormThemeAddBottomAction(Request $request)
    {
        return $this->customFormThemeAction($request);
    }

    /**
     * Advanced usage
     *
     * Collection of collections are useful on the most dynamic forms, and a good
     * way to test if the plugin is working as expected too.
     *
     * @Route("/collectionOfCollections", name="collectionOfCollections")
     * @Template()
     */
    public function collectionOfCollectionsAction(Request $request)
    {
        $data = [
            'collections' => [
                [new Value('a'), new Value('b'), new Value('c')],
                [new Value('d'), new Value('e'), new Value('f')],
                [new Value('g'), new Value('h'), new Value('i')],
            ],
        ];

        $form = $this
           ->get('form.factory')
           ->createNamedBuilder('form', Type\FormType::class, $data)
           ->add('collections', Type\CollectionType::class, [
               'entry_type'    => Type\CollectionType::class,
               'label'         => 'Add, move, remove collections',
               'entry_options' => [
                   'entry_type'    => ValueType::class,
                   'label'         => 'Add, move, remove values',
                   'entry_options' => [
                       'label' => 'Value',
                   ],
                   'allow_add'      => true,
                   'allow_delete'   => true,
                   'prototype'      => true,
                   'prototype_name' => '__children_name__',
                   'attr'           => [
                       'class' => 'child-collection',
                   ],
               ],
               'allow_add'      => true,
               'allow_delete'   => true,
               'prototype'      => true,
               'prototype_name' => '__parent_name__',
               'attr'           => [
                   'class' => 'parent-collection',
               ],
           ])
           ->add('submit', Type\SubmitType::class)
           ->getForm()
        ;

        $form->handleRequest($request);
        if ($form->isValid()) {
            $data = $form->getData();
        }

        return [
            'form' => $form->createView(),
            'data' => $data,
        ];
    }

    /**
     * Advanced usage
     *
     * Looks like there are weird behaviours with Doctrine:
     * https://github.com/ninsuo/symfony-collection/issues/7
     * Let's test that live!
     *
     * ... hmm, doesn't look bad anyway
     *
     * @Route(
     *      "/usageWithDoctrine/{name}",
     *      name = "usageWithDoctrine",
     *      defaults = {
     *          "name" = "example"
     *      }
     * )
     * @Template()
     */
    public function usageWithDoctrineAction(Request $request, $name)
    {
        $repo = $this->getDoctrine()->getRepository('FuzAppBundle:MyArray');

        $data = $repo->findOneByName($name);
        if (is_null($data)) {
            $data = $repo->create($name);
        }

        $form = $this->createForm(MyArrayType::class, $data);
        $form->handleRequest($request);

        $form->get('save')->isClicked() && $form->isValid() && $repo->save($data);

        return [
            'names' => $repo->getArrayNames(),
            'form'  => $form->createView(),
            'data'  => $data,
        ];
    }

    /**
     * Related to usageWithDoctrine demo
     *
     * @Route(
     *      "/usageWithDoctrineDelete/{name}",
     *      name = "usageWithDoctrineDelete"
     * )
     */
    public function usageWithDoctrineDeleteAction(Request $request, $name)
    {
        $repo = $this->getDoctrine()->getRepository('FuzAppBundle:MyArray');
        if (!is_null($data = $repo->findOneByName($name))) {
            $repo->delete($data);
        }

        return $this->forward('FuzAppBundle:Advanced:usageWithDoctrine', [
            'name' => 'example',
        ]);
    }

    /**
     * A form having a theme and containing several fields
     *
     * @Route(
     *      "/formHavingSeveralFields",
     *      name = "formHavingSeveralFields"
     * )
     * @Template()
     */
    public function formHavingSeveralFieldsAction(Request $request)
    {
        $address = new Address();
        $address->setName('Mickael Steller');
        $address->setCompany('fuz.org');
        $address->setStreet('41 rue de la Paix');
        $address->setPostalcode('75002');
        $address->setCity('Paris');
        $address->setCountry('France');

        $addresses = new Addresses();
        $addresses->getAddresses()->add($address);

        $form = $this->createForm(AddressesType::class, $addresses);
        if ($request->isMethod('POST')) {
            $form->handleRequest($request);
        }

        return [
            'form' => $form->createView(),
            'data' => $addresses,
        ];
    }

    /**
     * Another example of form theme
     *
     * @Route(
     *      "/fancyFormTheme",
     *      name = "fancyFormTheme"
     * )
     * @Template()
     */
    public function fancyFormThemeAction(Request $request)
    {
        $fancyCollection = new FancyCollection();

        for ($i = 0; $i < 3; $i++) {
            $fancy = new Fancy();
            $fancyCollection->getFancyCollection()->add($fancy);
        }

        $form = $this->createForm(FancyCollectionType::class, $fancyCollection);

        $form->handleRequest($request);
        if ($form->isValid()) {
            $data = $form->getData();
        }

        return [
            'form' => $form->createView(),
            'data' => $fancyCollection,
        ];
    }
}
<?php

namespace Fuz\AppBundle\Entity;

use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ORM\Mapping as ORM;

/**
 * MyArray
 *
 * @ORM\Table(
 *      name="my_array",
 *      uniqueConstraints={@ORM\UniqueConstraint(name="name_idx", columns={"name"})}
 * )
 * @ORM\Entity(repositoryClass="Fuz\AppBundle\Repository\MyArrayRepository")
 */
class MyArray
{
    /**
     * @var int
     *
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    protected $id;

    /**
     * @var string
     *
     * @ORM\Column(name="name", type="string", length=255)
     */
    protected $name;

    /**
     * @var ArrayCollection
     *
     * @ORM\OneToMany(targetEntity="MyElement", mappedBy="array", cascade={"all"}, orphanRemoval=true)
     */
    protected $elements;

    public function __construct()
    {
        $this->elements = new ArrayCollection();
    }

    public function getId()
    {
        return $this->id;
    }

    public function getName()
    {
        return $this->name;
    }

    public function setName($name)
    {
        $this->name = $name;

        return $this;
    }

    public function getElements()
    {
        return $this->elements;
    }
}
<?php

namespace Fuz\AppBundle\Entity;

use Doctrine\ORM\Mapping as ORM;

/**
 * MyElement
 *
 * @ORM\Table(name="my_element"),
 * @ORM\Entity
 */
class MyElement
{
    /**
     * @var int
     *
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    protected $id;

    /**
     * @var MyArray
     *
     * @ORM\ManyToOne(targetEntity="MyArray", inversedBy="elements")
     * @ORM\JoinColumn(name="my_array_id", referencedColumnName="id")
     */
    protected $array;

    /**
     * @var string
     *
     * @ORM\Column(name="value", type="string", length=255)
     */
    protected $value;

    public function setId($id)
    {
        $this->id = $id;

        return $this;
    }

    public function getId()
    {
        return $this->id;
    }

    public function setArray(MyArray $array)
    {
        $this->array = $array;

        return $this;
    }

    public function getArray()
    {
        return $this->array;
    }

    public function setValue($value)
    {
        $this->value = $value;

        return $this;
    }

    public function getValue()
    {
        return $this->value;
    }
}
<?php

namespace Fuz\AppBundle\Form;

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\TextType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;

class MyArrayType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder->add('name', TextType::class, [
                'label' => 'Array name:',
        ]);

        $builder->add('elements', CollectionType::class, [
            'label'        => 'Add an element...',
            'entry_type'   => MyElementType::class,
            'allow_add'    => true,
            'allow_delete' => true,
            'prototype'    => true,
            'required'     => false,
            'by_reference' => true,
            'delete_empty' => true,
            'attr'         => [
                'class' => 'doctrine-sample',
            ],
        ]);

        $builder->add('save', SubmitType::class, [
                'label' => 'Save this array',
        ]);
    }

    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults([
            'data_class' => 'Fuz\AppBundle\Entity\MyArray',
        ]);
    }

    public function getBlockPrefix()
    {
        return 'my_array';
    }
}
<?php

namespace Fuz\AppBundle\Form;

use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;

class MyElementType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder->add('value', TextType::class, [
            'required' => false,
        ]);
    }

    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults([
            'data_class' => 'Fuz\AppBundle\Entity\MyElement',
        ]);
    }

    public function getBlockPrefix()
    {
        return 'my_element';
    }
}
<?php

namespace Fuz\AppBundle\Repository;

use Doctrine\DBAL\Exception\UniqueConstraintViolationException;
use Doctrine\ORM\EntityRepository;
use Fuz\AppBundle\Entity\MyArray;

/**
 * MyArrayRepository.
 */
class MyArrayRepository extends EntityRepository
{
    public function create($name)
    {
        $data = new MyArray();
        $data->setName($name);
        try {
            $this->_em->persist($data);
            $this->_em->flush();
        } catch (UniqueConstraintViolationException $e) {
            return null;
        }

        return $data;
    }

    public function save(MyArray $data)
    {
        foreach ($data->getElements() as $element) {
            $element->setArray($data);
        }
        try {
            $this->_em->persist($data);
            $this->_em->flush();
        } catch (UniqueConstraintViolationException $e) {
            return null;
        }

        return $data;
    }

    public function getArrayNames()
    {
        $arrays = $this
            ->_em
            ->createQuery("
               SELECT arr.name
               FROM Fuz\AppBundle\Entity\MyArray arr
            ")
            ->execute();
        $names = [];
        foreach ($arrays as $array) {
            $names[] = $array['name'];
        }

        return $names;
    }

    public function delete(MyArray $data)
    {
        foreach ($data->getElements() as $element) {
            $this->_em->remove($element);
        }
        $this->_em->remove($data);
        $this->_em->flush();
    }
}

{% block my_element_label %}{% endblock %}
{% block my_element_errors %}{% endblock %}

{% block my_element_widget %}

    <div class="row">
        <div class="col-md-7">
            {{ form_widget(form.value) }}
        </div>
        <div class="col-md-2">
            <a href="#" class="collection-up btn btn-default">Up</a>
            <a href="#" class="collection-down btn btn-default">Down</a>
        </div>
        <div class="col-md-2">
            <a href="#" class="collection-remove btn btn-default">Remove</a>
            <a href="#" class="collection-add btn btn-default">Add</a>
        </div>
        <div class="col-md-1">
            <a href="#" class="collection-duplicate btn btn-default">Duplicate</a>
        </div>
    </div>

{% endblock %}
{% extends 'FuzAppBundle::layout.html.twig' %}

{% block extra_js %}
    <script src="{{ asset('js/jquery.collection.js') }}"></script>
{% endblock %}

{% block title %}Advanced usage: example with Doctrine{% endblock %}

{% block body %}

    <h2>{{ block('title') }}</h2>

    <p>
        That's not really an <i>advanced</i> topic, but the sample will be a bit hard to read (as it takes many files),
        so let's say it targets more experienced Symfony users.
    </p>

    <p>
        In this demo, we're displaying a MyArray of MyElements, both persisted into the database. The MyArray entity
        only have an id and a name, and MyElement has id, MyArray's id and a value. This is quite the same as we seen
        in all demos, but persisted.
    </p>

    <div class="text-center">
        <input type="button" id="new" class="btn btn-default" value="Create new array"/>
    </div>

    {%
        form_theme form
            'jquery.collection.html.twig'
            'FuzAppBundle:Advanced:doctrine-theme.html.twig'
    %}
    {{ form(form) }}

    <hr/>

    {% if names|length %}
        Existing arrays:
        <table class="table">
            <thead>
                <th>Name</th>
                <th>Open</th>
                <th>Delete</th>
            </thead>
            <tbody>
                {% for name in names %}
                    <tr>
                        <td>{{ name }}</td>
                        <td>
                            {% if data.name != name %}<a href="{{ path('usageWithDoctrine', {'name': name}) }}">Open</a>{% endif %}
                        </td>
                        <td><a href="{{ path('usageWithDoctrineDelete', {'name': name}) }}">Delete</a></td>
                    </tr>
                {% endfor %}
            </tbody>
        </table>
    {% endif %}

    {{
        tabs([
            'Base/BaseController.php',
            'Controller/AdvancedController.php',
            'Resources/views/Advanced/usageWithDoctrine.html.twig',
            'Resources/views/Advanced/doctrine-theme.html.twig',
            'Entity/MyArray.php',
            'Form/MyArrayType.php',
            'Entity/MyElement.php',
            'Form/MyElementType.php',
            'Repository/MyArrayRepository.php',
        ])
    }}

{% endblock %}

{% block script %}

    <script type="text/javascript">

        // only useful for the "new" button...
        $('#new').on('click', function() {
           var name = prompt("Which name would you like to use?");
           if (name) {
               var uri = '{{ path('usageWithDoctrine', {'name': 'a'}) }}';
               document.location = uri.substr(0, uri.length - 1) + encodeURIComponent(name);
           }
        });

        $('.doctrine-sample').collection();

    </script>

{% endblock %}