Skip to content

Commit 6c88364

Browse files
committed
Added documentation for buttons in forms
1 parent 38bbca1 commit 6c88364

File tree

11 files changed

+284
-11
lines changed

11 files changed

+284
-11
lines changed

book/forms.rst

Lines changed: 119 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,7 @@ from inside a controller::
101101
$form = $this->createFormBuilder($task)
102102
->add('task', 'text')
103103
->add('dueDate', 'date')
104+
->add('save', 'submit')
104105
->getForm();
105106

106107
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``
125126
corresponding to the ``task`` and ``dueDate`` properties of the ``Task`` class.
126127
You've also assigned each a "type" (e.g. ``text``, ``date``), which, among
127128
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.
128134

129135
Symfony2 comes with many built-in types that will be discussed shortly
130136
(see :ref:`book-forms-type-reference`).
@@ -147,17 +153,13 @@ helper functions:
147153
{# src/Acme/TaskBundle/Resources/views/Default/new.html.twig #}
148154
<form action="{{ path('task_new') }}" method="post" {{ form_enctype(form) }}>
149155
{{ form_widget(form) }}
150-
151-
<input type="submit" />
152156
</form>
153157

154158
.. code-block:: html+php
155159

156160
<!-- src/Acme/TaskBundle/Resources/views/Default/new.html.php -->
157161
<form action="<?php echo $view['router']->generate('task_new') ?>" method="post" <?php echo $view['form']->enctype($form) ?> >
158162
<?php echo $view['form']->widget($form) ?>
159-
160-
<input type="submit" />
161163
</form>
162164

163165
.. image:: /images/book/form-simple.png
@@ -194,7 +196,7 @@ it into a format that's suitable for being rendered in an HTML form.
194196
Support for "hasser" methods was added in Symfony 2.1.
195197

196198
.. index::
197-
single: Forms; Handling form submission
199+
single: Forms; Handling form submissions
198200

199201
Handling Form Submissions
200202
~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -215,6 +217,7 @@ controller::
215217
$form = $this->createFormBuilder($task)
216218
->add('task', 'text')
217219
->add('dueDate', 'date')
220+
->add('save', 'submit')
218221
->getForm();
219222

220223
if ($request->isMethod('POST')) {
@@ -265,6 +268,42 @@ possible paths:
265268
Redirecting a user after a successful form submission prevents the user
266269
from being able to hit "refresh" and re-post the data.
267270

271+
.. index::
272+
single: Forms; Multiple Submit Buttons
273+
274+
.. _book-form-submitting-multiple-buttons:
275+
276+
Submitting Forms with Multiple Buttons
277+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
278+
279+
.. versionadded:: 2.3
280+
Support for buttons in forms was added in Symfony 2.3.
281+
282+
When your form contains more than one submit button, you will want to check
283+
which of the buttons was clicked to adapt the program flow in your controller.
284+
Let's add a second button with the caption "Save and add" to our form::
285+
286+
$form = $this->createFormBuilder($task)
287+
->add('task', 'text')
288+
->add('dueDate', 'date')
289+
->add('save', 'submit')
290+
->add('saveAndAdd', 'submit')
291+
->getForm();
292+
293+
In your controller, use the button's
294+
:method:`Symfony\\Component\\Form\\ClickableInterface\\isClicked` method for
295+
querying if the "Save and add" button was clicked::
296+
297+
if ($form->isValid()) {
298+
// perform some action, such as saving the task to the database
299+
300+
$nextAction = $form->get('saveAndAdd')->isClicked()
301+
? 'task_new'
302+
: 'task_success';
303+
304+
return $this->redirect($this->generateUrl($nextAction));
305+
}
306+
268307
.. index::
269308
single: Forms; Validation
270309

@@ -408,16 +447,49 @@ method::
408447
In both of these cases, *only* the ``registration`` validation group will
409448
be used to validate the underlying object.
410449

411-
Groups based on Submitted Data
412-
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
450+
.. index::
451+
single: Forms; Disabling validation
452+
453+
Disabling Validation
454+
~~~~~~~~~~~~~~~~~~~~
455+
456+
.. versionadded:: 2.3
457+
The ability to set ``validation_groups`` to false is new to version 2.3.
458+
Setting it to an empty array was already supported before.
459+
460+
Sometimes it is useful to suppress the validation of a form altogether. For
461+
these cases, you can skip the call to :method:`Symfony\\Component\\Form\\FormInterface::isValid`
462+
in your controller. If this is not possible, you can alternatively set the
463+
``validation_groups`` option to ``false`` or an empty array::
464+
465+
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
466+
467+
public function setDefaultOptions(OptionsResolverInterface $resolver)
468+
{
469+
$resolver->setDefaults(array(
470+
'validation_groups' => false,
471+
));
472+
}
473+
474+
Note that when you do that, the form will still run basic integrity checks,
475+
for example whether an uploaded file was too large or whether non-existing
476+
fields were submitted. If you want to suppress validation completely, remove
477+
the :method:`Symfony\\Component\\Form\\FormInterface::isValid` call from your
478+
controller.
479+
480+
.. index::
481+
single: Forms; Validation groups based on submitted data
482+
483+
Groups based on the Submitted Data
484+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
413485

414486
.. versionadded:: 2.1
415487
The ability to specify a callback or Closure in ``validation_groups``
416488
is new to version 2.1
417489

418490
If you need some advanced logic to determine the validation groups (e.g.
419491
based on submitted data), you can set the ``validation_groups`` option
420-
to an array callback, or a ``Closure``::
492+
to an array callback::
421493

422494
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
423495

@@ -431,7 +503,7 @@ to an array callback, or a ``Closure``::
431503
This will call the static method ``determineValidationGroups()`` on the
432504
``Client`` class after the form is bound, but before validation is executed.
433505
The Form object is passed as an argument to that method (see next example).
434-
You can also define whole logic inline by using a Closure::
506+
You can also define whole logic inline by using a ``Closure``::
435507

436508
use Symfony\Component\Form\FormInterface;
437509
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
@@ -450,6 +522,44 @@ You can also define whole logic inline by using a Closure::
450522
));
451523
}
452524

525+
.. index::
526+
single: Forms; Validation groups based on clicked button
527+
528+
Groups based on the Clicked Button
529+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
530+
531+
.. versionadded:: 2.3
532+
Support for buttons in forms was added in Symfony 2.3.
533+
534+
When your form contains multiple submit buttons, you can change the validation
535+
group depending on which button is used to submit the form. For example,
536+
consider a form in a wizard that lets you advance to the next step or go back
537+
to the previous step. Let's assume also that when returning to the previous
538+
step, the data of the form should be saved, but not validated.
539+
540+
First, we need to add the two buttons to the form::
541+
542+
$form = $this->createFormBuilder($task)
543+
// ...
544+
->add('nextStep', 'submit')
545+
->add('previousStep', 'submit')
546+
->getForm();
547+
548+
Then, we configure the button for returning to the previous step to run
549+
specific validation groups. In this example, we want it to suppress validation,
550+
so we set its ``validation_groups`` options to false::
551+
552+
$form = $this->createFormBuilder($task)
553+
// ...
554+
->add('previousStep', 'submit', array(
555+
'validation_groups' => false,
556+
))
557+
->getForm();
558+
559+
Now the form will skip your validation constraints. It will still validate
560+
basic integrity constraints, such as checking whether an uploaded file was too
561+
large or whether you tried to submit text in a number field.
562+
453563
.. index::
454564
single: Forms; Built-in field types
455565

reference/forms/types.rst

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ Form Types Reference
99
:hidden:
1010

1111
types/birthday
12+
types/button
1213
types/checkbox
1314
types/choice
1415
types/collection
@@ -31,7 +32,9 @@ Form Types Reference
3132
types/percent
3233
types/radio
3334
types/repeated
35+
types/reset
3436
types/search
37+
types/submit
3538
types/text
3639
types/textarea
3740
types/time

reference/forms/types/button.rst

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
.. index::
2+
single: Forms; Fields; button
3+
4+
button Field Type
5+
=================
6+
7+
.. versionadded:: 2.3
8+
The ``button`` type is new in version 2.3
9+
10+
A simple, non-responsive button.
11+
12+
+----------------------+------------------------------------------------------------------------------------------------------------------------+
13+
| Rendered as | ``button`` tag |
14+
+----------------------+------------------------------------------------------------------------------------------------------------------------+
15+
| Options | - `attr`_ |
16+
| | - `disabled`_ |
17+
| | - `label`_ |
18+
| | - `translation_domain`_ |
19+
+----------------------+------------------------------------------------------------------------------------------------------------------------+
20+
| Parent type | none |
21+
+----------------------+------------------------------------------------------------------------------------------------------------------------+
22+
| Class | :class:`Symfony\\Component\\Form\\Extension\\Core\\Type\\ButtonType` |
23+
+----------------------+------------------------------------------------------------------------------------------------------------------------+
24+
25+
Options
26+
-------
27+
28+
.. include:: /reference/forms/types/options/button_attr.rst.inc
29+
30+
.. include:: /reference/forms/types/options/button_disabled.rst.inc
31+
32+
.. include:: /reference/forms/types/options/button_label.rst.inc
33+
34+
.. include:: /reference/forms/types/options/button_translation_domain.rst.inc

reference/forms/types/map.rst.inc

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,8 +49,15 @@ Hidden Fields
4949
* :doc:`hidden</reference/forms/types/hidden>`
5050
* :doc:`csrf</reference/forms/types/csrf>`
5151

52+
Buttons
53+
~~~~~~~
54+
55+
* :doc:`button</reference/forms/types/button>`
56+
* :doc:`reset</reference/forms/types/reset>`
57+
* :doc:`submit</reference/forms/types/submit>`
58+
5259
Base Fields
5360
~~~~~~~~~~~
5461

5562
* :doc:`field</reference/forms/types/field>`
56-
* :doc:`form</reference/forms/types/form>`
63+
* :doc:`form</reference/forms/types/form>`

reference/forms/types/options/attr.rst.inc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ attr
33

44
**type**: array **default**: Empty array
55

6-
If you want to add extra attributes to HTML field representation
6+
If you want to add extra attributes to the HTML field representation,
77
you can use ``attr`` option. It's an associative array with HTML attribute
88
as a key. This can be useful when you need to set a custom class for some widget::
99

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
attr
2+
~~~~
3+
4+
**type**: array **default**: Empty array
5+
6+
If you want to add extra attributes to the HTML representation of the button,
7+
you can use ``attr`` option. It's an associative array with HTML attribute
8+
as a key. This can be useful when you need to set a custom class for the button::
9+
10+
$builder->add('save', 'button', array(
11+
'attr' => array('class' => 'save'),
12+
));
13+
14+
15+
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
disabled
2+
~~~~~~~~
3+
4+
**type**: ``boolean`` **default**: ``false``
5+
6+
If you don't want a user to be able to click a button, you can set the disabled
7+
option to true. It will not be possible to submit the form with this button,
8+
not even when bypassing the browser and sending an request manually, for
9+
example with cURL.
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
label
2+
~~~~~
3+
4+
**type**: ``string`` **default**: The label is "guessed" from the field name
5+
6+
Sets the label that will be displayed on the button. The label can also be
7+
directly set inside the template:
8+
9+
.. code-block:: jinja
10+
11+
{{ form_widget(form.save, { 'label': 'Click me' }) }}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
translation_domain
2+
~~~~~~~~~~~~~~~~~~
3+
4+
**type**: ``string`` **default**: ``messages``
5+
6+
This is the translation domain that will be used for any labels or options
7+
that are rendered for this button.

reference/forms/types/reset.rst

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
.. index::
2+
single: Forms; Fields; reset
3+
4+
reset Field Type
5+
================
6+
7+
.. versionadded:: 2.3
8+
The ``submit`` type is new in version 2.3
9+
10+
A button that resets all fields to their original values.
11+
12+
+----------------------+------------------------------------------------------------------------------------------------------------------------+
13+
| Rendered as | ``input`` ``reset`` tag |
14+
+----------------------+------------------------------------------------------------------------------------------------------------------------+
15+
| Inherited | - `attr`_ |
16+
| options | - `disabled`_ |
17+
| | - `label`_ |
18+
| | - `translation_domain`_ |
19+
+----------------------+------------------------------------------------------------------------------------------------------------------------+
20+
| Parent type | :doc:`button</reference/forms/types/button>` |
21+
+----------------------+------------------------------------------------------------------------------------------------------------------------+
22+
| Class | :class:`Symfony\\Component\\Form\\Extension\\Core\\Type\\ResetType` |
23+
+----------------------+------------------------------------------------------------------------------------------------------------------------+
24+
25+
Inherited options
26+
-----------------
27+
28+
.. include:: /reference/forms/types/options/button_attr.rst.inc
29+
30+
.. include:: /reference/forms/types/options/button_disabled.rst.inc
31+
32+
.. include:: /reference/forms/types/options/button_label.rst.inc
33+
34+
.. include:: /reference/forms/types/options/button_translation_domain.rst.inc

0 commit comments

Comments
 (0)