@@ -101,6 +101,7 @@ from inside a controller::
101
101
$form = $this->createFormBuilder($task)
102
102
->add('task', 'text')
103
103
->add('dueDate', 'date')
104
+ ->add('save', 'submit')
104
105
->getForm();
105
106
106
107
return $this->render('AcmeTaskBundle:Default:new.html.twig', array(
@@ -125,6 +126,11 @@ In this example, you've added two fields to your form - ``task`` and ``dueDate``
125
126
corresponding to the ``task `` and ``dueDate `` properties of the ``Task `` class.
126
127
You've also assigned each a "type" (e.g. ``text ``, ``date ``), which, among
127
128
other things, determines which HTML form tag(s) is rendered for that field.
129
+ At last, you added a submit button for submitting the form to the server.
130
+
131
+ .. versionadded :: 2.3
132
+ Support for submit buttons was added in Symfony 2.3. Before that, you had
133
+ to add buttons to the form's HTML manually.
128
134
129
135
Symfony2 comes with many built-in types that will be discussed shortly
130
136
(see :ref: `book-forms-type-reference `).
@@ -145,11 +151,13 @@ helper functions:
145
151
.. code-block :: html+jinja
146
152
147
153
{# src/Acme/TaskBundle/Resources/views/Default/new.html.twig #}
154
+
148
155
{{ form(form) }}
149
156
150
157
.. code-block :: html+php
151
158
152
159
<!-- src/Acme/TaskBundle/Resources/views/Default/new.html.php -->
160
+
153
161
<?php echo $view['form']->form($form) ?>
154
162
155
163
.. image :: /images/book/form-simple.png
@@ -187,7 +195,7 @@ it into a format that's suitable for being rendered in an HTML form.
187
195
Support for "hasser" methods was added in Symfony 2.1.
188
196
189
197
.. index ::
190
- single: Forms; Handling form submission
198
+ single: Forms; Handling form submissions
191
199
192
200
.. _book-form-handling-form-submissions :
193
201
@@ -210,6 +218,7 @@ controller::
210
218
$form = $this->createFormBuilder($task)
211
219
->add('task', 'text')
212
220
->add('dueDate', 'date')
221
+ ->add('save', 'submit')
213
222
->getForm();
214
223
215
224
$form->handleRequest($request);
@@ -262,6 +271,42 @@ possible paths:
262
271
Redirecting a user after a successful form submission prevents the user
263
272
from being able to hit "refresh" and re-post the data.
264
273
274
+ .. index ::
275
+ single: Forms; Multiple Submit Buttons
276
+
277
+ .. _book-form-submitting-multiple-buttons :
278
+
279
+ Submitting Forms with Multiple Buttons
280
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
281
+
282
+ .. versionadded :: 2.3
283
+ Support for buttons in forms was added in Symfony 2.3.
284
+
285
+ When your form contains more than one submit button, you will want to check
286
+ which of the buttons was clicked to adapt the program flow in your controller.
287
+ Let's add a second button with the caption "Save and add" to our form::
288
+
289
+ $form = $this->createFormBuilder($task)
290
+ ->add('task', 'text')
291
+ ->add('dueDate', 'date')
292
+ ->add('save', 'submit')
293
+ ->add('saveAndAdd', 'submit')
294
+ ->getForm();
295
+
296
+ In your controller, use the button's
297
+ :method: `Symfony\\ Component\\ Form\\ ClickableInterface::isClicked ` method for
298
+ querying if the "Save and add" button was clicked::
299
+
300
+ if ($form->isValid()) {
301
+ // ... perform some action, such as saving the task to the database
302
+
303
+ $nextAction = $form->get('saveAndAdd')->isClicked()
304
+ ? 'task_new'
305
+ : 'task_success';
306
+
307
+ return $this->redirect($this->generateUrl($nextAction));
308
+ }
309
+
265
310
.. index ::
266
311
single: Forms; Validation
267
312
@@ -405,16 +450,50 @@ method::
405
450
In both of these cases, *only * the ``registration `` validation group will
406
451
be used to validate the underlying object.
407
452
408
- Groups based on Submitted Data
409
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
453
+ .. index ::
454
+ single: Forms; Disabling validation
455
+
456
+ Disabling Validation
457
+ ~~~~~~~~~~~~~~~~~~~~
458
+
459
+ .. versionadded :: 2.3
460
+ The ability to set ``validation_groups `` to false was added in Symfony 2.3,
461
+ although setting it to an empty array achieved the same result in previous
462
+ versions.
463
+
464
+ Sometimes it is useful to suppress the validation of a form altogether. For
465
+ these cases, you can skip the call to :method: `Symfony\\ Component\\ Form\\ FormInterface::isValid `
466
+ in your controller. If this is not possible, you can alternatively set the
467
+ ``validation_groups `` option to ``false `` or an empty array::
468
+
469
+ use Symfony\Component\OptionsResolver\OptionsResolverInterface;
470
+
471
+ public function setDefaultOptions(OptionsResolverInterface $resolver)
472
+ {
473
+ $resolver->setDefaults(array(
474
+ 'validation_groups' => false,
475
+ ));
476
+ }
477
+
478
+ Note that when you do that, the form will still run basic integrity checks,
479
+ for example whether an uploaded file was too large or whether non-existing
480
+ fields were submitted. If you want to suppress validation completely, remove
481
+ the :method: `Symfony\\ Component\\ Form\\ FormInterface::isValid ` call from your
482
+ controller.
483
+
484
+ .. index ::
485
+ single: Forms; Validation groups based on submitted data
486
+
487
+ Groups based on the Submitted Data
488
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
410
489
411
490
.. versionadded :: 2.1
412
491
The ability to specify a callback or Closure in ``validation_groups ``
413
492
is new to version 2.1
414
493
415
494
If you need some advanced logic to determine the validation groups (e.g.
416
495
based on submitted data), you can set the ``validation_groups `` option
417
- to an array callback, or a `` Closure `` ::
496
+ to an array callback::
418
497
419
498
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
420
499
@@ -428,7 +507,7 @@ to an array callback, or a ``Closure``::
428
507
This will call the static method ``determineValidationGroups() `` on the
429
508
``Client `` class after the form is submitted, but before validation is executed.
430
509
The Form object is passed as an argument to that method (see next example).
431
- You can also define whole logic inline by using a Closure::
510
+ You can also define whole logic inline by using a `` Closure `` ::
432
511
433
512
use Symfony\Component\Form\FormInterface;
434
513
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
@@ -447,6 +526,44 @@ You can also define whole logic inline by using a Closure::
447
526
));
448
527
}
449
528
529
+ .. index ::
530
+ single: Forms; Validation groups based on clicked button
531
+
532
+ Groups based on the Clicked Button
533
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
534
+
535
+ .. versionadded :: 2.3
536
+ Support for buttons in forms was added in Symfony 2.3.
537
+
538
+ When your form contains multiple submit buttons, you can change the validation
539
+ group depending on which button is used to submit the form. For example,
540
+ consider a form in a wizard that lets you advance to the next step or go back
541
+ to the previous step. Let's assume also that when returning to the previous
542
+ step, the data of the form should be saved, but not validated.
543
+
544
+ First, we need to add the two buttons to the form::
545
+
546
+ $form = $this->createFormBuilder($task)
547
+ // ...
548
+ ->add('nextStep', 'submit')
549
+ ->add('previousStep', 'submit')
550
+ ->getForm();
551
+
552
+ Then, we configure the button for returning to the previous step to run
553
+ specific validation groups. In this example, we want it to suppress validation,
554
+ so we set its ``validation_groups `` options to false::
555
+
556
+ $form = $this->createFormBuilder($task)
557
+ // ...
558
+ ->add('previousStep', 'submit', array(
559
+ 'validation_groups' => false,
560
+ ))
561
+ ->getForm();
562
+
563
+ Now the form will skip your validation constraints. It will still validate
564
+ basic integrity constraints, such as checking whether an uploaded file was too
565
+ large or whether you tried to submit text in a number field.
566
+
450
567
.. index ::
451
568
single: Forms; Built-in field types
452
569
0 commit comments