Skip to content

Added documentation for buttons in forms #2489

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
May 3, 2013
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
129 changes: 120 additions & 9 deletions book/forms.rst
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@ from inside a controller::
$form = $this->createFormBuilder($task)
->add('task', 'text')
->add('dueDate', 'date')
->add('save', 'submit')
->getForm();

return $this->render('AcmeTaskBundle:Default:new.html.twig', array(
Expand All @@ -125,6 +126,11 @@ In this example, you've added two fields to your form - ``task`` and ``dueDate``
corresponding to the ``task`` and ``dueDate`` properties of the ``Task`` class.
You've also assigned each a "type" (e.g. ``text``, ``date``), which, among
other things, determines which HTML form tag(s) is rendered for that field.
At last, you added a submit button for submitting the form to the server.

.. versionadded:: 2.3
Support for submit buttons was added in Symfony 2.3. Before that, you had
to add buttons to the form's HTML manually.

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

<input type="submit" />
</form>

.. code-block:: html+php

<!-- src/Acme/TaskBundle/Resources/views/Default/new.html.php -->
<form action="<?php echo $view['router']->generate('task_new') ?>" method="post" <?php echo $view['form']->enctype($form) ?> >
<?php echo $view['form']->widget($form) ?>

<input type="submit" />
</form>

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

.. index::
single: Forms; Handling form submission
single: Forms; Handling form submissions

Handling Form Submissions
~~~~~~~~~~~~~~~~~~~~~~~~~
Expand All @@ -215,6 +217,7 @@ controller::
$form = $this->createFormBuilder($task)
->add('task', 'text')
->add('dueDate', 'date')
->add('save', 'submit')
->getForm();

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

.. index::
single: Forms; Multiple Submit Buttons

.. _book-form-submitting-multiple-buttons:

Submitting Forms with Multiple Buttons
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

.. versionadded:: 2.3
Support for buttons in forms was added in Symfony 2.3.

When your form contains more than one submit button, you will want to check
which of the buttons was clicked to adapt the program flow in your controller.
Let's add a second button with the caption "Save and add" to our form::

$form = $this->createFormBuilder($task)
->add('task', 'text')
->add('dueDate', 'date')
->add('save', 'submit')
->add('saveAndAdd', 'submit')
->getForm();

In your controller, use the button's
:method:`Symfony\\Component\\Form\\ClickableInterface::isClicked` method for
querying if the "Save and add" button was clicked::

if ($form->isValid()) {
// ... perform some action, such as saving the task to the database

$nextAction = $form->get('saveAndAdd')->isClicked()
? 'task_new'
: 'task_success';

return $this->redirect($this->generateUrl($nextAction));
}

.. index::
single: Forms; Validation

Expand Down Expand Up @@ -408,16 +447,50 @@ method::
In both of these cases, *only* the ``registration`` validation group will
be used to validate the underlying object.

Groups based on Submitted Data
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.. index::
single: Forms; Disabling validation

Disabling Validation
~~~~~~~~~~~~~~~~~~~~

.. versionadded:: 2.3
The ability to set ``validation_groups`` to false was added in Symfony 2.3,
although setting it to an empty array achieved the same result in previous
versions.

Sometimes it is useful to suppress the validation of a form altogether. For
these cases, you can skip the call to :method:`Symfony\\Component\\Form\\FormInterface::isValid`
in your controller. If this is not possible, you can alternatively set the
``validation_groups`` option to ``false`` or an empty array::

use Symfony\Component\OptionsResolver\OptionsResolverInterface;

public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(array(
'validation_groups' => false,
));
}

Note that when you do that, the form will still run basic integrity checks,
for example whether an uploaded file was too large or whether non-existing
fields were submitted. If you want to suppress validation completely, remove
the :method:`Symfony\\Component\\Form\\FormInterface::isValid` call from your
controller.

.. index::
single: Forms; Validation groups based on submitted data

Groups based on the Submitted Data
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

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

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

use Symfony\Component\OptionsResolver\OptionsResolverInterface;

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

use Symfony\Component\Form\FormInterface;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
Expand All @@ -450,6 +523,44 @@ You can also define whole logic inline by using a Closure::
));
}

.. index::
single: Forms; Validation groups based on clicked button

Groups based on the Clicked Button
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

.. versionadded:: 2.3
Support for buttons in forms was added in Symfony 2.3.

When your form contains multiple submit buttons, you can change the validation
group depending on which button is used to submit the form. For example,
consider a form in a wizard that lets you advance to the next step or go back
to the previous step. Let's assume also that when returning to the previous
step, the data of the form should be saved, but not validated.

First, we need to add the two buttons to the form::

$form = $this->createFormBuilder($task)
// ...
->add('nextStep', 'submit')
->add('previousStep', 'submit')
->getForm();

Then, we configure the button for returning to the previous step to run
specific validation groups. In this example, we want it to suppress validation,
so we set its ``validation_groups`` options to false::

$form = $this->createFormBuilder($task)
// ...
->add('previousStep', 'submit', array(
'validation_groups' => false,
))
->getForm();

Now the form will skip your validation constraints. It will still validate
basic integrity constraints, such as checking whether an uploaded file was too
large or whether you tried to submit text in a number field.

.. index::
single: Forms; Built-in field types

Expand Down
3 changes: 3 additions & 0 deletions reference/forms/types.rst
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ Form Types Reference
:hidden:

types/birthday
types/button
types/checkbox
types/choice
types/collection
Expand All @@ -31,7 +32,9 @@ Form Types Reference
types/percent
types/radio
types/repeated
types/reset
types/search
types/submit
types/text
types/textarea
types/time
Expand Down
34 changes: 34 additions & 0 deletions reference/forms/types/button.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
.. index::
single: Forms; Fields; button

button Field Type
=================

.. versionadded:: 2.3
The ``button`` type was added in Symfony 2.3

A simple, non-responsive button.

+----------------------+----------------------------------------------------------------------+
| Rendered as | ``button`` tag |
+----------------------+----------------------------------------------------------------------+
| Options | - `attr`_ |
| | - `disabled`_ |
| | - `label`_ |
| | - `translation_domain`_ |
+----------------------+----------------------------------------------------------------------+
| Parent type | none |
+----------------------+----------------------------------------------------------------------+
| Class | :class:`Symfony\\Component\\Form\\Extension\\Core\\Type\\ButtonType` |
+----------------------+----------------------------------------------------------------------+

Options
-------

.. include:: /reference/forms/types/options/button_attr.rst.inc

.. include:: /reference/forms/types/options/button_disabled.rst.inc

.. include:: /reference/forms/types/options/button_label.rst.inc

.. include:: /reference/forms/types/options/button_translation_domain.rst.inc
9 changes: 8 additions & 1 deletion reference/forms/types/map.rst.inc
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,15 @@ Hidden Fields
* :doc:`hidden</reference/forms/types/hidden>`
* :doc:`csrf</reference/forms/types/csrf>`

Buttons
~~~~~~~

* :doc:`button</reference/forms/types/button>`
* :doc:`reset</reference/forms/types/reset>`
* :doc:`submit</reference/forms/types/submit>`

Base Fields
~~~~~~~~~~~

* :doc:`field</reference/forms/types/field>`
* :doc:`form</reference/forms/types/form>`
* :doc:`form</reference/forms/types/form>`
2 changes: 1 addition & 1 deletion reference/forms/types/options/attr.rst.inc
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ attr

**type**: array **default**: Empty array

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

Expand Down
15 changes: 15 additions & 0 deletions reference/forms/types/options/button_attr.rst.inc
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
attr
~~~~

**type**: array **default**: Empty array

If you want to add extra attributes to the HTML representation of the button,
you can use ``attr`` option. It's an associative array with HTML attribute
as a key. This can be useful when you need to set a custom class for the button::

$builder->add('save', 'button', array(
'attr' => array('class' => 'save'),
));



9 changes: 9 additions & 0 deletions reference/forms/types/options/button_disabled.rst.inc
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
disabled
~~~~~~~~

**type**: ``boolean`` **default**: ``false``

If you don't want a user to be able to click a button, you can set the disabled
option to true. It will not be possible to submit the form with this button,
not even when bypassing the browser and sending a request manually, for
example with cURL.
17 changes: 17 additions & 0 deletions reference/forms/types/options/button_label.rst.inc
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
label
~~~~~

**type**: ``string`` **default**: The label is "guessed" from the field name

Sets the label that will be displayed on the button. The label can also be
directly set inside the template:

.. configuration-block::

.. code-block:: html+jinja

{{ form_widget(form.save, { 'label': 'Click me' }) }}

.. code-block:: html+php

<?php echo $view['form']->widget($form['save'], array('label' => 'Click me')) ?>
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
translation_domain
~~~~~~~~~~~~~~~~~~

**type**: ``string`` **default**: ``messages``

This is the translation domain that will be used for any labels or options
that are rendered for this button.
34 changes: 34 additions & 0 deletions reference/forms/types/reset.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
.. index::
single: Forms; Fields; reset

reset Field Type
================

.. versionadded:: 2.3
The ``reset`` type was added in Symfony 2.3

A button that resets all fields to their original values.

+----------------------+---------------------------------------------------------------------+
| Rendered as | ``input`` ``reset`` tag |
+----------------------+---------------------------------------------------------------------+
| Inherited | - `attr`_ |
| options | - `disabled`_ |
| | - `label`_ |
| | - `translation_domain`_ |
+----------------------+---------------------------------------------------------------------+
| Parent type | :doc:`button</reference/forms/types/button>` |
+----------------------+---------------------------------------------------------------------+
| Class | :class:`Symfony\\Component\\Form\\Extension\\Core\\Type\\ResetType` |
+----------------------+---------------------------------------------------------------------+

Inherited options
-----------------

.. include:: /reference/forms/types/options/button_attr.rst.inc

.. include:: /reference/forms/types/options/button_disabled.rst.inc

.. include:: /reference/forms/types/options/button_label.rst.inc

.. include:: /reference/forms/types/options/button_translation_domain.rst.inc
Loading