Skip to content

Commit 6aebe02

Browse files
committed
feature #14241 [Form] Add new way of mapping form data using callback functions (yceruto)
This PR was merged into the master branch. Discussion ---------- [Form] Add new way of mapping form data using callback functions Documenting new feature symfony/symfony#37968 I don't think we need to cover all possible situations; the current example covers 3 of them, except the second one, but it seems enough for me, wdyt? > [...] you'll have to write your own data mapper in the following situations: >* When the property path differs for reading and writing >* When several form fields are mapped to a single method >* When you need to read data based on the model's state >* When the mapping of the model depends on the submitted form data ... By the way, the second situation "when several form fields are mapped to a single method" can be achieved this way: ```php $builder ->add('foo', TextType::class, [ 'setter' => function (Foobar $foobar, string $value) use (&$foo) { $foo = $value; }, ]) ->add('bar', TextType::class, [ 'setter' => function (Foobar $foobar, string $bar) use (&$foo) { $foobar->doSomething($foo, $bar); }, ]) ; ``` Since the data mapper will follow the same order in which the fields were defined, we can trust that the foo "setter" will be executed first and so the second "setter" will have the right value at the moment this function `$foobar->doSomething($foo, $bar)` is being executed. --- ping @alcaeus :) Commits ------- 53fb3c7 Add new way of mapping form data
2 parents 58c9014 + 53fb3c7 commit 6aebe02

File tree

1 file changed

+39
-0
lines changed

1 file changed

+39
-0
lines changed

form/data_mappers.rst

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,45 @@ method::
189189
Cool! When using the ``ColorType`` form, the custom data mapper methods will
190190
create a new ``Color`` object now.
191191

192+
Mapping Form Fields Using Callbacks
193+
-----------------------------------
194+
195+
Conveniently, you can also map data from and into a form field by using the
196+
``getter`` and ``setter`` options. For example, suppose you have a form with some
197+
fields and only one of them needs to be mapped in some special way or you only
198+
need to change how it's written into the underlying object. In that case, register
199+
a PHP callable that is able to write or read to/from that specific object::
200+
201+
public function buildForm(FormBuilderInterface $builder, array $options)
202+
{
203+
// ...
204+
205+
$builder->add('state', ChoiceType::class, [
206+
'choices' => [
207+
'active' => true,
208+
'paused' => false,
209+
],
210+
'getter' => function (Task $task, FormInterface $form): bool {
211+
return !$task->isCancelled() && !$task->isPaused();
212+
},
213+
'setter' => function (Task &$task, bool $state, FormInterface $form): void {
214+
if ($state) {
215+
$task->activate();
216+
} else {
217+
$task->pause();
218+
}
219+
},
220+
]);
221+
}
222+
223+
If available, these options have priority over the property path accessor and
224+
the default data mapper will still use the :doc:`PropertyAccess component </components/property_access>`
225+
for the other form fields.
226+
227+
.. versionadded:: 5.2
228+
229+
The ``getter`` and ``setter`` options were introduced in Symfony 5.2.
230+
192231
.. caution::
193232

194233
When a form has the ``inherit_data`` option set to ``true``, it does not use the data mapper and

0 commit comments

Comments
 (0)