diff --git a/book/controller.rst b/book/controller.rst index d5869219282..06422cf8351 100644 --- a/book/controller.rst +++ b/book/controller.rst @@ -325,7 +325,7 @@ working with forms, for example:: { $form = $this->createForm(...); - $form->bind($request); + $form->handleRequest($request); // ... } @@ -663,7 +663,8 @@ For example, imagine you're processing a form submit:: { $form = $this->createForm(...); - $form->bind($this->getRequest()); + $form->handleRequest($this->getRequest()); + if ($form->isValid()) { // do some sort of processing diff --git a/book/forms.rst b/book/forms.rst index 272eae5e86e..f9c7e69e8fc 100644 --- a/book/forms.rst +++ b/book/forms.rst @@ -145,35 +145,27 @@ helper functions: .. code-block:: html+jinja {# src/Acme/TaskBundle/Resources/views/Default/new.html.twig #} -
+ {{ form(form) }} .. code-block:: html+php - + form($form) ?> .. image:: /images/book/form-simple.png :align: center .. note:: - This example assumes that you've created a route called ``task_new`` - that points to the ``AcmeTaskBundle:Default:new`` controller that - was created earlier. + This example assumes that you submit the form in a "POST" request and to + the same URL that it was displayed in. You will learn later how to + change the request method and the target URL of the form. -That's it! By printing ``form_widget(form)``, each field in the form is -rendered, along with a label and error message (if there is one). As easy -as this is, it's not very flexible (yet). Usually, you'll want to render each -form field individually so you can control how the form looks. You'll learn how -to do that in the ":ref:`form-rendering-template`" section. +That's it! By printing ``form(form)``, each field in the form is rendered, along +with a label and error message (if there is one). As easy as this is, it's not +very flexible (yet). Usually, you'll want to render each form field individually +so you can control how the form looks. You'll learn how to do that in the +":ref:`form-rendering-template`" section. Before moving on, notice how the rendered ``task`` input field has the value of the ``task`` property from the ``$task`` object (i.e. "Write a blog post"). @@ -201,7 +193,7 @@ Handling Form Submissions The second job of a form is to translate user-submitted data back to the properties of an object. To make this happen, the submitted data from the -user must be bound to the form. Add the following functionality to your +user must be written into the form. Add the following functionality to your controller:: // ... @@ -217,53 +209,54 @@ controller:: ->add('dueDate', 'date') ->getForm(); - if ($request->isMethod('POST')) { - $form->bind($request); + $form->handleRequest($request); - if ($form->isValid()) { - // perform some action, such as saving the task to the database + if ($form->isValid()) { + // perform some action, such as saving the task to the database - return $this->redirect($this->generateUrl('task_success')); - } + return $this->redirect($this->generateUrl('task_success')); } // ... } -.. versionadded:: 2.1 - The ``bind`` method was made more flexible in Symfony 2.1. It now accepts - the raw client data (same as before) or a Symfony Request object. This - is preferred over the deprecated ``bindRequest`` method. - -Now, when submitting the form, the controller binds the submitted data to the -form, which translates that data back to the ``task`` and ``dueDate`` properties -of the ``$task`` object. This all happens via the ``bind()`` method. - -.. note:: - - As soon as ``bind()`` is called, the submitted data is transferred - to the underlying object immediately. This happens regardless of whether - or not the underlying data is actually valid. +.. versionadded:: 2.3 + The :method:`Symfony\Component\Form\FormInterface::handleRequest` method was + added in Symfony 2.3. Before you had to do some manual work to achieve the + same result. This controller follows a common pattern for handling forms, and has three possible paths: -#. When initially loading the page in a browser, the request method is ``GET`` - and the form is simply created and rendered; +#. When initially loading the page in a browser, the form is simply created and + rendered. :method:`Symfony\Component\Form\FormInterface::handleRequest` + recognizes that the form was not submitted and does nothing. + :method:`Symfony\Component\Form\FormInterface::isValid` returns ``false`` + if the form was not submitted. -#. When the user submits the form (i.e. the method is ``POST``) with invalid - data (validation is covered in the next section), the form is bound and - then rendered, this time displaying all validation errors; +#. When the user submits the form, :method:`Symfony\Component\Form\FormInterface::handleRequest` + recognizes this and immediately writes the submitted data back into the + ``task`` and ``dueDate`` properties of the ``$task`` object. Then this object + is validated. If it is invalid (validation is covered in the next section), + :method:`Symfony\Component\Form\FormInterface::isValid` returns ``false`` + again, so the form is rendered together with all validation errors; -#. When the user submits the form with valid data, the form is bound and - you have the opportunity to perform some actions using the ``$task`` - object (e.g. persisting it to the database) before redirecting the user - to some other page (e.g. a "thank you" or "success" page). + .. note:: -.. note:: + You can use the method :method:`Symfony\Component\Form\FormInterface::isBound` + to check whether a form was submitted, regardless of whether or not the + submitted data is actually valid. + +#. When the user submits the form with valid data, the submitted data is again + written into the form, but this time :method:`Symfony\Component\Form\FormInterface::isValid` + returns ``true``. Now you have the opportunity to perform some actions using + the ``$task`` object (e.g. persisting it to the database) before redirecting + the user to some other page (e.g. a "thank you" or "success" page). - Redirecting a user after a successful form submission prevents the user - from being able to hit "refresh" and re-post the data. + .. note:: + + 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; Validation @@ -429,7 +422,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. +``Client`` class after the form is submitted, 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:: @@ -605,35 +598,30 @@ of code. Of course, you'll usually need much more flexibility when rendering: .. code-block:: html+jinja {# src/Acme/TaskBundle/Resources/views/Default/new.html.twig #} - + {{ form_end(form) }} .. code-block:: html+php - + end($form) ?> Take a look at each part: -* ``form_enctype(form)`` - If at least one field is a file upload field, this - renders the obligatory ``enctype="multipart/form-data"``; +* ``form_start(form)`` - Renders the start tag of the form. * ``form_errors(form)`` - Renders any errors global to the whole form (field-specific errors are displayed next to each field); @@ -642,10 +630,8 @@ Take a look at each part: form widget for the given field (e.g. ``dueDate``) inside, by default, a ``div`` element; -* ``form_rest(form)`` - Renders any fields that have not yet been rendered. - It's usually a good idea to place a call to this helper at the bottom of - each form (in case you forgot to output a field or don't want to bother - manually rendering hidden fields). This helper is also useful for taking +* ``form_end()`` - Renders the end tag of the form and any fields that have not + yet been rendered. This is useful for rendering hidden fields and taking advantage of the automatic :ref:`CSRF Protection