Symfony formbuilder met JQueryUI Sortable

Overzicht Reageren

Sponsored by: Vacatures door Monsterboard

Frank Nietbelangrijk

Frank Nietbelangrijk

16/02/2015 23:56:26
Quote Anchor link
Beste PHPers,

Ik wil graag een formulier maken waarin checkboxen toegevoegd/bewerkt/verwijderd kunnen worden en ook nog eens op willekeurige volgorde gezet kunnen worden Met Symfony's "formbuilder" en JQueryUI Sortable. Deze checkbox-collectie wordt dan later in een ander formulier voor de eindgebruiker geplaatst. zoiets dus

Ik heb een Entity genaamd FlexOption. Deze Entity staat zeg maar voor één checkbox.
Daarna heb ik rechtstreeks in mijn Controller een Form aangemaakt met slechts één formType namelijk het type collection. Rechtstreeks in de controller omdat ik geen Entity nodig heb. Ik weet even niet zo goed te verwoorden waarom ik die niet nodig heb.. maar het komt er op neer dat er slechts één lijst met FlexOptions zal bestaan er hoeft dus geen one-to-many in de database te komen.

De controller:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
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
<?php
    public function indexAction(Request $request)
    {

        $em = $this->getDoctrine()->getManager();

        $entities = $em->getRepository('MainBundle:FlexOption')->findAll();

        $defaultData = array();
        $form = $this->createFormBuilder($defaultData)
            ->
add('options', 'collection', array(
                            'type' => new \MainBundle\Form\FlexOptionType(),
                            'allow_add' => true,
                            'allow_delete' => true,
                            'by_reference' => false,
                            'data' => $entities,
            ))
            ->
add('Verzenden', 'submit')
            ->
getForm();

            if ($request->isMethod('POST')) {
                $form->bind($request);

                if ($form->isValid()) {
                    print_r($form->getData());
                    exit;
                }
            }


        return array(
            'form' => $form->createView(),
        );
    }

?>


Na het verzenden en Validatie haal ik de gegevens op met $form->getData(). Het resultaat is een array als hieronder:

Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
Array
(
    [options] => Array
        (
            [0] => MainBundle\Entity\FlexOption Object
                (
                    [id:MainBundle\Entity\FlexOption:private] => 3
                    [label:MainBundle\Entity\FlexOption:private] => test
                    [sequence:MainBundle\Entity\FlexOption:private] => 0
                    [deleted:MainBundle\Entity\FlexOption:private] =>
                )

            [1] => MainBundle\Entity\FlexOption Object
                (
                    [id:MainBundle\Entity\FlexOption:private] => 1
                    [label:MainBundle\Entity\FlexOption:private] => Film / Fotografie
                    [sequence:MainBundle\Entity\FlexOption:private] => 1
                    [deleted:MainBundle\Entity\FlexOption:private] =>
                )

        )

)


Nu Moet ik deze array dus weer in (een ArrayCollection van) FlexOption objecten zien te zetten.
Ik vermoed dat ik Serializer->denormalize() aan de slag moet?
Wie kan mij een duwtje in de goede richting geven?

Alvast bedankt,
Frank
Gewijzigd op 17/02/2015 00:01:07 door Frank Nietbelangrijk
 
PHP hulp

PHP hulp

26/12/2024 09:53:44
 
Frank Nietbelangrijk

Frank Nietbelangrijk

30/03/2015 09:14:47
Quote Anchor link
Robotje?

Het is inmiddels op een andere manier opgelost maar de vraag is nog niet beantwoord.
Gewijzigd op 30/03/2015 09:16:02 door Frank Nietbelangrijk
 
Wouter J

Wouter J

30/03/2015 12:06:55
Quote Anchor link
Eerst even wat dingen (aannemende dat je op zijn minst Symfony 2.3 gebruikt):

* Form#bind() is deprecated, gebruik Form#bindRequest()
* De request method check gebeurd in Form#isSubmitted(), welke gecalled wordt in Form#isValid(). Het is niet nodig om dit zelf te controleren. De method kun je aanpassen met de 'method' form option

Je controller wordt dan iets als:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<?php
    public function indexAction(Request $request)
    {

        $em = $this->getDoctrine()->getManager();

        $entities = $em->getRepository('MainBundle:FlexOption')->findAll();

        $defaultData = array();
        $form = $this->createFormBuilder($defaultData)
            // ...
            ->getForm();

        $form->bindRequest($request);

        // de isSubmitted() call is niet nodig, maar de best practices
        // raden aan het er wel in te voegen, om je code beter leesbaar te maken

        if ($form->isSubmitted() && $form->isValid()) {
            // waarom eigenlijk niet $form->get('options')->getData() ?
            print_r($form->getData();
        }


        return array('form' => $form->createView());
    }

?>


De rede dat je geen ArrayCollection terug krijgt is eigenlijk vrij simpel: Je gebruikt nergens een array collection. ObjectRepository#findAll() returned namelijk een array: https://github.com/doctrine/common/blob/master/lib/Doctrine/Common/Persistence/ObjectRepository.php#L41-46

Je kan een array overigens vrij makkelijk in een ArrayCollection omzetten:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
<?php
use Doctrine\Common\Collections\ArrayCollection;

// ...
$collection = new ArrayCollection($form->getData());
?>


Het mooiste is om dit in een form data transformer te stoppen (View -> Norm).
 
Frank Nietbelangrijk

Frank Nietbelangrijk

30/03/2015 13:23:28
Quote Anchor link
Hallo Wouter,

Als eerste ontzettend bedankt voor je reactie wederom.

Ik heb nog niet alles bestudeerd uit je bericht maar kan het zijn dat het handleRequest() moet zijn in plaats van bindRequest() ? Op die laatste krijg ik namelijk een foutmelding. Ik gebruik Symfony 2.6.





Toevoeging op 30/03/2015 13:32:36:

Oké je kan dus gewoon een array meegeven aan de constructor van ArrayCollection.

>> Het mooiste is om dit in een form data transformer te stoppen (View -> Norm).
Ik zie met behulp van Google dat daar informatie over te vinden is. Hiermee kan ik bovengenoemde data omzetten naar een gewone array of een arrayCollection?
 
Wouter J

Wouter J

01/04/2015 15:30:43
Quote Anchor link
>> Ik heb nog niet alles bestudeerd uit je bericht maar kan het zijn dat het handleRequest() moet zijn in plaats van bindRequest() ?

Inderdaad, typefoutje :)

>> Hiermee kan ik bovengenoemde data omzetten naar een gewone array of een arrayCollection?

Data transformers zijn een mooie en abstracte manier om waardes om te zetten. Elk form element heeft View data (het geen voor HTML gebruikt wordt), Norm data (normalized, het geen binnen de form gebruikt wordt) en Model data (de waarde die je entity/document/model krijgt). In het geval van een date form is de view data een array met dag, maand en jaar, de norm data een DateTime object en de model data bijv. een YYYY-MM-DD string.

Zodra je je form uit je controller haalt en er een form type van maakt zou ik aanraden om data transformers te gebruiken. Overigens een talk van de maker van de Form component over data transformers: https://www.youtube.com/watch?v=Q80b9XeLUEA
 
Frank Nietbelangrijk

Frank Nietbelangrijk

01/04/2015 17:39:47
Quote Anchor link
Bedankt Wouter ik zal gauw eens rustig het filmpje bekijken. Die data transformers lijken me erg interessant.

I owe you a beer..
 



Overzicht Reageren

 
 

Om de gebruiksvriendelijkheid van onze website en diensten te optimaliseren maken wij gebruik van cookies. Deze cookies gebruiken wij voor functionaliteiten, analytische gegevens en marketing doeleinden. U vindt meer informatie in onze privacy statement.