Skip to content

Commit 318ba88

Browse files
committed
Added information about the new form(), form_start() and form_end() helpers
1 parent 1dcfe8d commit 318ba88

File tree

9 files changed

+194
-112
lines changed

9 files changed

+194
-112
lines changed

book/forms.rst

+90-36
Original file line numberDiff line numberDiff line change
@@ -145,35 +145,27 @@ helper functions:
145145
.. code-block:: html+jinja
146146

147147
{# src/Acme/TaskBundle/Resources/views/Default/new.html.twig #}
148-
<form action="{{ path('task_new') }}" method="post" {{ form_enctype(form) }}>
149-
{{ form_widget(form) }}
150-
151-
<input type="submit" />
152-
</form>
148+
{{ form(form) }}
153149

154150
.. code-block:: html+php
155151

156152
<!-- src/Acme/TaskBundle/Resources/views/Default/new.html.php -->
157-
<form action="<?php echo $view['router']->generate('task_new') ?>" method="post" <?php echo $view['form']->enctype($form) ?> >
158-
<?php echo $view['form']->widget($form) ?>
159-
160-
<input type="submit" />
161-
</form>
153+
<?php echo $view['form']->form($form) ?>
162154

163155
.. image:: /images/book/form-simple.png
164156
:align: center
165157

166158
.. note::
167159

168-
This example assumes that you've created a route called ``task_new``
169-
that points to the ``AcmeTaskBundle:Default:new`` controller that
170-
was created earlier.
160+
This example assumes that you submit the form in a "POST" request and to
161+
the same URL that it was displayed in. You will learn later how to
162+
change the request method and the target URL of the form.
171163

172-
That's it! By printing ``form_widget(form)``, each field in the form is
173-
rendered, along with a label and error message (if there is one). As easy
174-
as this is, it's not very flexible (yet). Usually, you'll want to render each
175-
form field individually so you can control how the form looks. You'll learn how
176-
to do that in the ":ref:`form-rendering-template`" section.
164+
That's it! By printing ``form(form)``, each field in the form is rendered, along
165+
with a label and error message (if there is one). As easy as this is, it's not
166+
very flexible (yet). Usually, you'll want to render each form field individually
167+
so you can control how the form looks. You'll learn how to do that in the
168+
":ref:`form-rendering-template`" section.
177169

178170
Before moving on, notice how the rendered ``task`` input field has the value
179171
of the ``task`` property from the ``$task`` object (i.e. "Write a blog post").
@@ -605,35 +597,30 @@ of code. Of course, you'll usually need much more flexibility when rendering:
605597
.. code-block:: html+jinja
606598

607599
{# src/Acme/TaskBundle/Resources/views/Default/new.html.twig #}
608-
<form action="{{ path('task_new') }}" method="post" {{ form_enctype(form) }}>
600+
{{ form_start(form) }}
609601
{{ form_errors(form) }}
610602

611603
{{ form_row(form.task) }}
612604
{{ form_row(form.dueDate) }}
613605

614-
{{ form_rest(form) }}
615-
616606
<input type="submit" />
617-
</form>
607+
{{ form_end(form) }}
618608

619609
.. code-block:: html+php
620610

621611
<!-- src/Acme/TaskBundle/Resources/views/Default/newAction.html.php -->
622-
<form action="<?php echo $view['router']->generate('task_new') ?>" method="post" <?php echo $view['form']->enctype($form) ?>>
612+
<?php echo $view['form']->start($form) ?>
623613
<?php echo $view['form']->errors($form) ?>
624614

625615
<?php echo $view['form']->row($form['task']) ?>
626616
<?php echo $view['form']->row($form['dueDate']) ?>
627617

628-
<?php echo $view['form']->rest($form) ?>
629-
630618
<input type="submit" />
631-
</form>
619+
<?php echo $view['form']->end($form) ?>
632620

633621
Take a look at each part:
634622

635-
* ``form_enctype(form)`` - If at least one field is a file upload field, this
636-
renders the obligatory ``enctype="multipart/form-data"``;
623+
* ``form_start(form)`` - Renders the start tag of the form.
637624

638625
* ``form_errors(form)`` - Renders any errors global to the whole form
639626
(field-specific errors are displayed next to each field);
@@ -642,10 +629,8 @@ Take a look at each part:
642629
form widget for the given field (e.g. ``dueDate``) inside, by default, a
643630
``div`` element;
644631

645-
* ``form_rest(form)`` - Renders any fields that have not yet been rendered.
646-
It's usually a good idea to place a call to this helper at the bottom of
647-
each form (in case you forgot to output a field or don't want to bother
648-
manually rendering hidden fields). This helper is also useful for taking
632+
* ``form_end()`` - Renders the end tag of the form and any fields that have not
633+
yet been rendered. This is useful for rendering hidden fields and taking
649634
advantage of the automatic :ref:`CSRF Protection<forms-csrf>`.
650635

651636
The majority of the work is done by the ``form_row`` helper, which renders
@@ -740,7 +725,7 @@ field:
740725

741726
.. code-block:: html+jinja
742727

743-
{{ form_widget(form.task, { 'attr': {'class': 'task_field'} }) }}
728+
{{ form_widget(form.task, {'attr': {'class': 'task_field'}}) }}
744729

745730
.. code-block:: html+php
746731

@@ -783,6 +768,75 @@ available in the :doc:`reference manual</reference/forms/twig_reference>`.
783768
Read this to know everything about the helpers available and the options
784769
that can be used with each.
785770

771+
.. index::
772+
single: Forms; Changing the action and method
773+
774+
.. _book-forms-changing-action-and-method:
775+
776+
Changing the Action and Method of a Form
777+
----------------------------------------
778+
779+
So far, we have used the ``form_start()`` helper to render the form's start tag
780+
and assumed that each form is submitted to the same URL in a POST request.
781+
Sometimes you want to change these parameters. You can do so in a few different
782+
ways. If you build your form in the controller, you can use ``setAction()`` and
783+
``setMethod()``::
784+
785+
$form = $this->createFormBuilder($task)
786+
->setAction($this->generateUrl('target_route'))
787+
->setMethod('GET')
788+
->add('task', 'text')
789+
->add('dueDate', 'date')
790+
->getForm();
791+
792+
.. note::
793+
794+
This example assumes that you've created a route called ``target_route``
795+
that points to the controller that processes the form.
796+
797+
In :ref:`book-form-creating-form-classes` you will learn how to outsource the
798+
form building code into separate classes. When using such a form class in the
799+
controller, you can pass the action and method as form options::
800+
801+
$form = $this->createForm(new TaskType(), $task, array(
802+
'action' => $this->generateUrl('target_route'),
803+
'method' => 'GET',
804+
));
805+
806+
At last, you can override the action and method in the template by passing them
807+
to the ``form()`` or the ``form_start()`` helper:
808+
809+
.. configuration-block::
810+
811+
.. code-block:: html+jinja
812+
813+
{# src/Acme/TaskBundle/Resources/views/Default/new.html.twig #}
814+
{{ form(form, {'action': path('target_route'), 'method': 'GET'}) }}
815+
816+
{{ form_start(form, {'action': path('target_route'), 'method': 'GET'}) }}
817+
818+
.. code-block:: html+php
819+
820+
<!-- src/Acme/TaskBundle/Resources/views/Default/newAction.html.php -->
821+
<?php echo $view['form']->form($form, array(
822+
'action' => $view['router']->generate('target_route'),
823+
'method' => 'GET',
824+
)) ?>
825+
826+
<?php echo $view['form']->start($form, array(
827+
'action' => $view['router']->generate('target_route'),
828+
'method' => 'GET',
829+
)) ?>
830+
831+
.. note::
832+
833+
If the form's method is not GET or POST, but PUT, PATCH or DELETE, Symfony2
834+
will insert a hidden field with the name "_method" that stores this method.
835+
The form will be submitted in a normal POST request, but Symfony2's router
836+
is capable of detecting the "_method" parameter and will interpret the
837+
request as PUT, PATCH or DELETE request. Read the cookbook chapter
838+
":doc:`/cookbook/routing/method_parameters`" for more information.
839+
786840
.. index::
787841
single: Forms; Creating form classes
788842

@@ -1143,7 +1197,7 @@ renders the form:
11431197

11441198
{% form_theme form 'AcmeTaskBundle:Form:fields.html.twig' 'AcmeTaskBundle:Form:fields2.html.twig' %}
11451199

1146-
<form ...>
1200+
{{ form(form) }}
11471201

11481202
.. code-block:: html+php
11491203

@@ -1152,7 +1206,7 @@ renders the form:
11521206

11531207
<?php $view['form']->setTheme($form, array('AcmeTaskBundle:Form', 'AcmeTaskBundle:Form')) ?>
11541208

1155-
<form ...>
1209+
<?php echo $view['form']->form($form) ?>
11561210

11571211
The ``form_theme`` tag (in Twig) "imports" the fragments defined in the given
11581212
template and uses them when rendering the form. In other words, when the
@@ -1231,7 +1285,7 @@ are 4 possible *parts* of a form that can be rendered:
12311285

12321286
.. note::
12331287

1234-
There are actually 3 other *parts* - ``rows``, ``rest``, and ``enctype`` -
1288+
There are actually 2 other *parts* - ``rows`` and ``rest`` -
12351289
but you should rarely if ever need to worry about overriding them.
12361290

12371291
By knowing the field type (e.g. ``textarea``) and which part you want to

cookbook/doctrine/file_uploads.rst

-26
Original file line numberDiff line numberDiff line change
@@ -251,32 +251,6 @@ The following controller shows you how to handle the entire process::
251251
return array('form' => $form->createView());
252252
}
253253

254-
.. note::
255-
256-
When writing the template, don't forget to set the ``enctype`` attribute:
257-
258-
.. configuration-block::
259-
260-
.. code-block:: html+jinja
261-
262-
<h1>Upload File</h1>
263-
264-
<form action="#" method="post" {{ form_enctype(form) }}>
265-
{{ form_widget(form) }}
266-
267-
<input type="submit" value="Upload Document" />
268-
</form>
269-
270-
.. code-block:: html+php
271-
272-
<h1>Upload File</h1>
273-
274-
<form action="#" method="post" <?php echo $view['form']->enctype($form) ?>>
275-
<?php echo $view['form']->widget($form) ?>
276-
277-
<input type="submit" value="Upload Document" />
278-
</form>
279-
280254
The previous controller will automatically persist the ``Document`` entity
281255
with the submitted name, but it will do nothing about the file and the ``path``
282256
property will be blank.

cookbook/doctrine/registration_form.rst

+5-9
Original file line numberDiff line numberDiff line change
@@ -232,10 +232,10 @@ controller for displaying the registration form::
232232
{
233233
public function registerAction()
234234
{
235-
$form = $this->createForm(
236-
new RegistrationType(),
237-
new Registration()
238-
);
235+
$registration = new Registration();
236+
$form = $this->createForm(new RegistrationType(), $registration, array(
237+
'action' => $this->generateUrl('create'),
238+
));
239239

240240
return $this->render(
241241
'AcmeAccountBundle:Account:register.html.twig',
@@ -249,11 +249,7 @@ and its template:
249249
.. code-block:: html+jinja
250250

251251
{# src/Acme/AccountBundle/Resources/views/Account/register.html.twig #}
252-
<form action="{{ path('create')}}" method="post" {{ form_enctype(form) }}>
253-
{{ form_widget(form) }}
254-
255-
<input type="submit" />
256-
</form>
252+
{{ form(form) }}
257253

258254
Finally, create the controller which handles the form submission. This performs
259255
the validation and saves the data into the database::

cookbook/form/form_collections.rst

+8-8
Original file line numberDiff line numberDiff line change
@@ -205,7 +205,7 @@ zero tags when first created).
205205

206206
{# ... #}
207207

208-
<form action="..." method="POST" {{ form_enctype(form) }}>
208+
{{ form_start(form) }}
209209
{# render the task's only field: description #}
210210
{{ form_row(form.description) }}
211211

@@ -216,27 +216,27 @@ zero tags when first created).
216216
<li>{{ form_row(tag.name) }}</li>
217217
{% endfor %}
218218
</ul>
219+
{{ form_end(form) }}
219220

220-
{{ form_rest(form) }}
221-
{# ... #}
222-
</form>
221+
{# ... #}
223222

224223
.. code-block:: html+php
225224

226225
<!-- src/Acme/TaskBundle/Resources/views/Task/new.html.php -->
227226

228227
<!-- ... -->
229228

230-
<form action="..." method="POST" ...>
229+
<?php echo $view['form']->start($form) ?>
230+
<!-- render the task's only field: description -->
231+
<?php echo $view['form']->row($form['description']) ?>
232+
231233
<h3>Tags</h3>
232234
<ul class="tags">
233235
<?php foreach($form['tags'] as $tag): ?>
234236
<li><?php echo $view['form']->row($tag['name']) ?></li>
235237
<?php endforeach; ?>
236238
</ul>
237-
238-
<?php echo $view['form']->rest($form) ?>
239-
</form>
239+
<?php echo $view['form']->end($form) ?>
240240

241241
<!-- ... -->
242242

cookbook/routing/method_parameters.rst

+4-25
Original file line numberDiff line numberDiff line change
@@ -86,28 +86,7 @@ Unfortunately, life isn't quite this simple, since most browsers do not
8686
support sending PUT and DELETE requests. Fortunately Symfony2 provides you
8787
with a simple way of working around this limitation. By including a ``_method``
8888
parameter in the query string or parameters of an HTTP request, Symfony2 will
89-
use this as the method when matching routes. This can be done easily in forms
90-
with a hidden field. Suppose you have a form for editing a blog post:
91-
92-
.. code-block:: html+jinja
93-
94-
<form action="{{ path('blog_update', {'slug': blog.slug}) }}" method="post">
95-
<input type="hidden" name="_method" value="PUT" />
96-
{{ form_widget(form) }}
97-
<input type="submit" value="Update" />
98-
</form>
99-
100-
The submitted request will now match the ``blog_update`` route and the ``updateAction``
101-
will be used to process the form.
102-
103-
Likewise the delete form could be changed to look like this:
104-
105-
.. code-block:: html+jinja
106-
107-
<form action="{{ path('blog_delete', {'slug': blog.slug}) }}" method="post">
108-
<input type="hidden" name="_method" value="DELETE" />
109-
{{ form_widget(delete_form) }}
110-
<input type="submit" value="Delete" />
111-
</form>
112-
113-
It will then match the ``blog_delete`` route.
89+
use this as the method when matching routes. Forms automatically include a
90+
hidden field for this parameter if their submission method is not GET or POST.
91+
See :ref:`the related chapter in the forms documentation<book-forms-changing-action-and-method>`
92+
for more information.

0 commit comments

Comments
 (0)