My name is
Jurgens du Toit.
Systems Developer.
Problem Solver.
Technology and Solving Problems are my passion. I'm a South African that loves my wife, life, and coding.
I’ve been working on teach-a-rific.com in my spare time, and I’m learning a lot about how Symfony 2 Forms work. One thing I need to do a lot, is to show a form with a entity field pre-populated. In this situation you also don’t want the user to be able to edit the field. This is how I did it.
First, you need to retrieve the mapped entity, in this case a Student
, and set it
in the entity which you’re creating a form for. In this case a ContactDetail
.
This all happens in the newAction
method of the ContactDetailController
.
Notice how I save the student ID in a session variable. More on this later.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<?php
//ContactDetailController::newAction
$detail = new ContactDetail();
if ($studentId = $request->query->get('student_id')) {
$student = $this
->getDoctrine()
->getManager()
->getRepository('NotesNoteBundle:Student')
->find($studentId);
if ($student) {
$this->get('session')->set('contact_detail:create:student', $studentId);
$detail->setStudent($student);
}
}
$form = $this->createForm(new ContactDetailType(), $detail);
On to the form. Quite simply, if the entity already has a Student
, don’t add the
field for the student.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<?php
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
class ContactDetailType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
if ($builder->getData()->getStudent() === null) {
$builder->add('student');
}
$builder
->add('type', 'choice', array('choices' => array('Email' => 'Email', 'Cellphone' => 'Cellphone')))
->add('content')
;
}
}
On to the actual form. If the student field is defined in the form, display the form widget. Otherwise display the student in an uneditable text input. Displaying the student can be skipped if it’s not necessary.
1
2
3
4
5
6
7
8
9
10
{% if form.student is defined %}
{{ form_row(form.student, { form_type: 'horizontal' }) }}
{% elseif form.vars.data.student.id is defined %}
<div class="control-group">
<label class="control-label">Student</label>
<div class="controls">
<span class="input uneditable-input">{{ form.vars.data.student }}</span>
</div>
</div>
{% endif %}
And on to the updateAction
. Just get the Student
whose ID we stored in the session,
and set it on the ContactDetail
before populating the form:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
<?php
//ContactDetailController::createAction
$entity = new ContactDetail();
if ($studentId = $this->get('session')->get('contact_detail:create:student')) {
$student = $this
->getDoctrine()
->getManager()
->getRepository('NotesNoteBundle:Student')
->find($studentId);
if ($student) {
$entity->setStudent($student);
}
}
Simple enough. Any suggestions on how to improve it, or comments on how to do it differently?