Bart Callens
Bart Callens

Reputation: 28

displaying a collection in symfony 2 form with data from a foreign table

I'm a newbie at symfony and I can't find a solution for my problem regarding displaying a form the correct way.

I've got three tables: activities, presences and persons

desc activities;
+----------+--------------+------+-----+---------+----------------+
| Field    | Type         | Null | Key | Default | Extra          |
+----------+--------------+------+-----+---------+----------------+
| id       | int(11)      | NO   | PRI | NULL    | auto_increment |
| start    | datetime     | NO   |     | NULL    |                |
| stop     | datetime     | YES  |     | NULL    |                |
| activity | varchar(100) | NO   |     | NULL    |                |
| location | varchar(45)  | NO   |     | NULL    |                |
| event_id | int(11)      | YES  | MUL | NULL    |                |
+----------+--------------+------+-----+---------+----------------+

desc presences;
+-------------+----------------------------------------------+------+-----+---------+-------+
| Field       | Type                                         | Null | Key | Default | Extra |
+-------------+----------------------------------------------+------+-----+---------+-------+
| activity_id | int(11)                                      | NO   | PRI | NULL    |       |
| person_id   | int(11)                                      | NO   | PRI | NULL    |       |
| status      | enum('afwezig','aanwezig','verontschuldigd') | NO   | PRI | afwezig |       |
+-------------+----------------------------------------------+------+-----+---------+-------+

desc persons;
+---------------+----------------+------+-----+-------------------+-----------------------------+
| Field         | Type           | Null | Key | Default           | Extra                       |
+---------------+----------------+------+-----+-------------------+-----------------------------+
| id            | int(11)        | NO   | PRI | NULL              | auto_increment              |
| firstname     | varchar(20)    | YES  |     | NULL              |                             |
| name          | varchar(30)    | YES  |     | NULL              |                             |

+---------------+----------------+------+-----+-------------------+-----------------------------+

I have created 2 formtypes One for the activities

public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add(
                'start',
                'datetime',
                array(
                    'label' => 'Start'

                )
            )
            ->add(
                'stop',
                'datetime',
                array(
                    'label' => 'Stop'

                )
            )
            ->add('activity', 'text', array('label' => 'Naam'))
            ->add('location', 'text', array('label' => 'Locatie'))
            ->add(
                'presences',
                'collection',
                array(
                    'type' => new PresencesType()
                )
            )
            ->add('save', 'submit', array('label' => 'Aanpassen'));
    }

And one for displaying the presences of a certain activity

  public function buildForm(FormBuilderInterface $builder, array $options)
        {
            $builder
                ->add(
                    'persons',
                    'entity',
                    array(
                        'class' => 'KHOSAdminBundle:Persons',
                        'label' => false,
                        'property' => 'fullname',
                        'read_only' => true,
                        'disabled' =>true
                    )
                )
                ->add(
                    'status',
                    'choice',
                    array(
                        'label' => false,
                        'multiple' => false,
                        'expanded' => true,
                        'choices' => array(
                            'afwezig' => 'afwezig',
                            'aanwezig' => 'aanwezig',
                            'verontschuldigd' => 'verontschuldigd'
                        )
                    )
                );
        }

using twig I can render this so it shows the details of the activity and below a list of presences.

{% for presence in form_activity.presences %}
   <div class="row">
       <div class="col-md-4">
         {{ form_row(presence.persons) }}
       </div>
       <div class="col-md-6">
          {{ form_row(presence.status, { 'style': 'inline' }) }}
       </div>
    </div>
{% endfor %}

All persons are dropdown's however and it takes ages to load. But I don't want that

I just want the details of the activity and below a list of all persons with there status as a radiobutton

Start: <<inputfield>>   Stop: <<inputfield>>
location: <<inputfield>>

firstname1 name1 : O afwezig  O  aanwezig  O verontschuldigd
firstname2 name2 : O afwezig  O  aanwezig  O verontschuldigd
firstname3 name3 : O afwezig  O  aanwezig  O verontschuldigd
firstname4 name4 : O afwezig  O  aanwezig  O verontschuldigd

Can someone help me?

Upvotes: 0

Views: 910

Answers (1)

Gildas
Gildas

Reputation: 1158

As I've suggested in comment, you should use a custom type for presence that does not use an entity field (you do not want to be able to edit the Person contained inside a Presence instance anyway, meaning you don't want a firstName and lastName fields).

Here's the php part:

<?php

namespace Demo {
    class Activity
    {
        protected $id;
        protected $start;
        protected $stop;

        /** @var Presence[] */
        protected $presences = [];

        // ...
    }

    class Presence {
        /** @var Activity */
        protected $activity;
        /** @var Person */
        protected $person;
        protected $status;

        // ...
    }

    class Person {
        protected $firstName;
        protected $lastName;
        /** @var Presence[] */
        protected $presences;

        // ...
    }

    class ActivityType extends AbstractType
    {
        public function buildForm(FormBuilderInterface $builder, array $options)
        {
            $builder
                ->add('start')
                ->add('stop')
                ->add('location')
                ->add('presences', 'collection', [
                    'type' => new PresenceType(),
                ])
            ;
        }

        public function getName()
        {
            return 'activity';
        }
    }

    class PresenceType extends AbstractType
    {
        public function buildForm(FormBuilderInterface $builder, array $options)
        {
            $builder
                ->add('status', 'choice', [
                    'multiple' => true,
                    'expanded' => false,
                    'choices' => [
                        'afwezig' => 'afwezig',
                        'aanwezig' => 'aanwezig',
                        'verontschuldigd' => 'verontschuldigd'
                    ]
                ])
            ;
        }

        public function getName()
        {
            return 'presence';
        }
    }
}

And the twig form theme (it may requires some tweaking to actually work, but the idea is to define how a presence form view is rendered when you call form_row(form) and form is PresenceType view instance):

{% block presence_row %}
    {{ form.vars.data.user.firstName }} {{ form.vars.data.user.lastName }} {{ form_widget(form) }}
    # form.vars.data contains the Presence instance
{% endblock %}

As you can see, I use the form theme to display the firstName and lastName of Person, and I haven't added it in my PresenceType class, that's because I don't need a firstName and lastName input fields.

Upvotes: 1

Related Questions