@@ -78,47 +78,118 @@ system to analyze the data on the object and modify the form based on the
78
78
Product object's data. In this entry, you'll learn how to add this level of
79
79
flexibility to your forms.
80
80
81
- .. _`cookbook-forms-event-subscriber ` :
81
+ .. _`cookbook-forms-event-listener ` :
82
82
83
- Adding An Event Subscriber To A Form Class
84
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
83
+ Adding an Event Listener to a Form Class
84
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
85
85
86
- So, instead of directly adding that "name" widget via your ``ProductType `` form
87
- class, let's delegate the responsibility of creating that particular field
88
- to an event subscriber::
86
+ So, instead of directly adding that ``name `` widget, the responsibility of
87
+ creating that particular field is delegated to an event listener::
89
88
90
89
// src/Acme/DemoBundle/Form/Type/ProductType.php
91
90
namespace Acme\DemoBundle\Form\Type;
92
91
93
92
// ...
94
- use Acme\DemoBundle\Form\EventListener\AddNameFieldSubscriber;
93
+ use Symfony\Component\Form\FormEvent;
94
+ use Symfony\Component\Form\FormEvents;
95
95
96
96
class ProductType extends AbstractType
97
97
{
98
98
public function buildForm(FormBuilderInterface $builder, array $options)
99
99
{
100
100
$builder->add('price');
101
101
102
- $builder->addEventSubscriber(new AddNameFieldSubscriber());
102
+ $builder->addEventListener(FormEvents::PRE_SET_DATA, function(FormEvent $event) {
103
+ // ... adding the name field if needed
104
+ });
103
105
}
104
106
105
107
// ...
106
108
}
107
109
108
- .. _`cookbook-forms-inside-subscriber-class` :
109
110
110
- Inside the Event Subscriber Class
111
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
111
+ The goal is to create a ``name `` field *only * if the underlying ``Product ``
112
+ object is new (e.g. hasn't been persisted to the database). Based on that,
113
+ the event listener might look like the following::
112
114
113
- The goal is to create a "name" field *only * if the underlying Product object
114
- is new (e.g. hasn't been persisted to the database). Based on that, the subscriber
115
- might look like the following:
115
+ // ...
116
+ public function buildForm(FormBuilderInterface $builder, array $options)
117
+ {
118
+ // ...
119
+ $builder->addEventListener(FormEvents::PRE_SET_DATA, function(FormEvent $event){
120
+ $product = $event->getData();
121
+ $form = $event->getForm();
122
+
123
+ // check if the Product object is "new"
124
+ // If no data is passed to the form, the data is "null".
125
+ // This should be considered a new "Product"
126
+ if (!$product || null !== $product->getId()) {
127
+ $form->add('name', 'text');
128
+ }
129
+ });
130
+ }
116
131
117
132
.. versionadded :: 2.2
118
- The ability to pass a string into :method: `FormInterface::add <Symfony\\ Component\\ Form\\ FormInterface::add> `
133
+ The ability to pass a string into
134
+ :method: `FormInterface::add <Symfony\\ Component\\ Form\\ FormInterface::add> `
119
135
was added in Symfony 2.2.
120
136
121
- .. code-block :: php
137
+ .. note ::
138
+ You can of course use any callback type instead of a closure, e.g. a method
139
+ call on the ``ProductType `` object itself for better readability::
140
+
141
+ // ...
142
+ class ProductType extends AbstractType
143
+ {
144
+ public function buildForm(FormBuilderInterface $builder, array $options)
145
+ {
146
+ // ...
147
+ $builder->addEventListener(FormEvents::PRE_SET_DATA, array($this, 'onPreSetData'));
148
+ }
149
+
150
+ public function onPreSetData(FormEvent $event){
151
+ // ...
152
+ }
153
+ }
154
+
155
+ .. note ::
156
+
157
+ The ``FormEvents::PRE_SET_DATA `` line actually resolves to the string
158
+ ``form.pre_set_data ``. :class: `Symfony\\ Component\\ Form\\ FormEvents `
159
+ serves an organizational purpose. It is a centralized location in which
160
+ you can find all of the various form events available. You can view the
161
+ full list of form events via the
162
+ :class: `Symfony\\ Component\\ Form\\ FormEvents ` class.
163
+
164
+ .. _`cookbook-forms-event-subscriber` :
165
+
166
+ Adding an Event Subscriber to a Form Class
167
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
168
+
169
+ For better reusability or if there is some heavy logic in your event listener,
170
+ you can also move the logic for creating the ``name `` field to an
171
+ :ref: `event subscriber <event_dispatcher-using-event-subscribers:ref: >`::
172
+
173
+ // src/Acme/DemoBundle/Form/Type/ProductType.php
174
+ namespace Acme\DemoBundle\Form\Type;
175
+
176
+ // ...
177
+ use Acme\DemoBundle\Form\EventListener\AddNameFieldSubscriber;
178
+
179
+ class ProductType extends AbstractType
180
+ {
181
+ public function buildForm(FormBuilderInterface $builder, array $options)
182
+ {
183
+ $builder->add('price');
184
+
185
+ $builder->addEventSubscriber(new AddNameFieldSubscriber());
186
+ }
187
+
188
+ // ...
189
+ }
190
+
191
+ Now the logic for creating the ``name `` field resides in it own subscriber
192
+ class::
122
193
123
194
// src/Acme/DemoBundle/Form/EventListener/AddNameFieldSubscriber.php
124
195
namespace Acme\DemoBundle\Form\EventListener;
@@ -138,29 +209,15 @@ might look like the following:
138
209
139
210
public function preSetData(FormEvent $event)
140
211
{
141
- $data = $event->getData();
212
+ $product = $event->getData();
142
213
$form = $event->getForm();
143
214
144
- // check if the product object is "new"
145
- // If you didn't pass any data to the form, the data is "null".
146
- // This should be considered a new "Product"
147
- if (!$data || !$data->getId()) {
215
+ if (!$product || null !== $product->getId()) {
148
216
$form->add('name', 'text');
149
217
}
150
218
}
151
219
}
152
220
153
- .. tip ::
154
-
155
- The ``FormEvents::PRE_SET_DATA `` line actually resolves to the string
156
- ``form.pre_set_data ``. :class: `Symfony\\ Component\\ Form\\ FormEvents ` serves
157
- an organizational purpose. It is a centralized location in which you can
158
- find all of the various form events available.
159
-
160
- .. note ::
161
-
162
- You can view the full list of form events via the :class: `Symfony\\ Component\\ Form\\ FormEvents `
163
- class.
164
221
165
222
.. _cookbook-form-events-user-data :
166
223
0 commit comments