Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

More 2.8 form updates#5909

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 ourterms of service andprivacy statement. We’ll occasionally send you account related emails.

Already on GitHub?Sign in to your account

Merged
weaverryan merged 5 commits into2.8frommore-form-tweaks
Nov 30, 2015
Merged
Show file tree
Hide file tree
Changes fromall 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
21 changes: 2 additions & 19 deletionsbest_practices/forms.rst
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -110,6 +110,7 @@ some developers configure form buttons in the controller::

use Symfony\Component\HttpFoundation\Request;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
use AppBundle\Entity\Post;
use AppBundle\Form\PostType;

Expand All@@ -121,7 +122,7 @@ some developers configure form buttons in the controller::
{
$post = new Post();
$form = $this->createForm(PostType::class, $post);
$form->add('submit','submit', array(
$form->add('submit',SubmitType::class, array(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

2.8 still requires 5.3.6, do you think it's safe to use 5.5 syntaxes?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

missing use statement btw

Copy link
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

I think we need to show the 5.5 syntax, because it's almost unusable if you can't use this syntax. But the idea is to also show the 5.3 syntax with a note about this in some cases early on in chapters. Basically, I want people to know that they need 5.5 to use the new syntax, but that they can use the old aliases until they actually need to upgrade to Symfony 3 (which requires 5.5). It's tricky.

And I think theuse statement is here - forSubmitType andPostType?

'label' => 'Create',
'attr' => array('class' => 'btn btn-default pull-right')
));
Expand DownExpand Up@@ -205,21 +206,3 @@ Second, we recommend using ``$form->isSubmitted()`` in the ``if`` statement
for clarity. This isn't technically needed, since ``isValid()`` first calls
``isSubmitted()``. But without this, the flow doesn't read well as it *looks*
like the form is *always* processed (even on the GET request).

Custom Form Field Types
-----------------------

.. best-practice::

Add the ``app_`` prefix to your custom form field types to avoid collisions.

Custom form field types inherit from the ``AbstractType`` class, which defines the
``getName()`` method to configure the name of that form type. These names must
be unique in the application.

If a custom form type uses the same name as any of the Symfony's built-in form
types, it will override it. The same happens when the custom form type matches
any of the types defined by the third-party bundles installed in your application.

Add the ``app_`` prefix to your custom form field types to avoid name collisions
that can lead to hard to debug errors.
29 changes: 14 additions & 15 deletionsbook/forms.rst
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -126,9 +126,11 @@ represented by its fully qualified class name. Among other things, it determines
which HTML form tag(s) is rendered for that field.

.. versionadded:: 2.8
To denote the form type, you have to use the fully qualified class name.
Before Symfony 2.8, you could use an alias for each type like ``'name'`` or
``'date'``.
To denote the form type, you have to use the fully qualified class name - like
``TextType::class`` in PHP 5.5+ or ``Symfony\Component\Form\Extension\Core\Type\TextType``.
Before Symfony 2.8, you could use an alias for each type like ``text`` or
``date``. The old alias syntax will still work until Symfony 3.0. For more details,
see the `2.8 UPGRADE Log`_.

Finally, you added a submit button with a custom label for submitting the form to
the server.
Expand DownExpand Up@@ -1004,7 +1006,7 @@ ways. If you build your form in the controller, you can use ``setAction()`` and
->setAction($this->generateUrl('target_route'))
->setMethod('GET')
->add('task', TextType::class)
->add('dueDate', DateType::clas)
->add('dueDate', DateType::class)
->add('save', SubmitType::class)
->getForm();

Expand All@@ -1017,7 +1019,10 @@ In :ref:`book-form-creating-form-classes` you will learn how to move the
form building code into separate classes. When using an external form class
in the controller, you can pass the action and method as form options::

$form = $this->createForm(new TaskType(), $task, array(
use AppBundle\Form\Type\TaskType;
// ...

$form = $this->createForm(TaskType::class, $task, array(
'action' => $this->generateUrl('target_route'),
'method' => 'GET',
));
Expand DownExpand Up@@ -1230,18 +1235,11 @@ Define your form type as a service.
.. code-block:: php

// src/AppBundle/Resources/config/services.php
useAppBundle\Form\Type\TaskType;
use ;

$definition = new Definition(TaskType::class, array(
new Reference('app.my_service'),
));
$container
->setDefinition(
'app.form.type.task',
$definition
)
$container->register('app.form.type.task', 'AppBundle\Form\Type\TaskType')
->addArgument(new Reference('app.my_service'))
->addTag('form.type')
;

Read :ref:`form-cookbook-form-field-service` for more information.

Expand DownExpand Up@@ -1978,3 +1976,4 @@ Learn more from the Cookbook
.. _`form_div_layout.html.twig`: https://github.com/symfony/symfony/blob/master/src/Symfony/Bridge/Twig/Resources/views/Form/form_div_layout.html.twig
.. _`Cross-site request forgery`: http://en.wikipedia.org/wiki/Cross-site_request_forgery
.. _`view on GitHub`: https://github.com/symfony/symfony/tree/master/src/Symfony/Bundle/FrameworkBundle/Resources/views/Form
.. _`2.8 UPGRADE Log`: https://github.com/symfony/symfony/blob/2.8/UPGRADE-2.8.md#form
2 changes: 1 addition & 1 deletionbook/validation.rst
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -230,7 +230,7 @@ workflow looks like the following from inside a controller::
public function updateAction(Request $request)
{
$author = new Author();
$form = $this->createForm(newAuthorType(), $author);
$form = $this->createForm(AuthorType::class, $author);

$form->handleRequest($request);

Expand Down
15 changes: 7 additions & 8 deletionscookbook/bundles/override.rst
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -105,17 +105,16 @@ associations. Learn more about this feature and its limitations in
Forms
-----

In order to override a form type, it has to be registered as a service (meaning
it is tagged as ``form.type``). You can then override it as you would override any
service as explained in `Services & Configuration`_. This, of course, will only
work if the type is referred to by its alias rather than being instantiated,
e.g.::
As of Symfony 2.8, form types are referred to by their fully-qualified class name::

$builder->add('name','custom_type');
$builder->add('name',CustomType::class);

rather than::
This means that you cannot override this by creating a sub-class of ``CustomType``
and registering it as a service, and tagging it with ``form.type`` (you *could*
do this in earlier version).

$builder->add('name', new CustomType());
Instead, you should use a "form type extension" to modify the existing form type.
For more information, see :doc:`/cookbook/form/create_form_type_extension`.

.. _override-validation:

Expand Down
5 changes: 3 additions & 2 deletionscookbook/controller/upload_file.rst
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -57,14 +57,15 @@ Then, add a new ``brochure`` field to the form that manages the ``Product`` enti
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\Form\Extension\Core\Type\FileType;

class ProductType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
// ...
->add('brochure','file', array('label' => 'Brochure (PDF file)'))
->add('brochure',FileType::class, array('label' => 'Brochure (PDF file)'))
// ...
;
}
Expand DownExpand Up@@ -116,7 +117,7 @@ Finally, you need to update the code of the controller that handles the form::
public function newAction(Request $request)
{
$product = new Product();
$form = $this->createForm(newProductType(), $product);
$form = $this->createForm(ProductType::class, $product);
$form->handleRequest($request);

if ($form->isValid()) {
Expand Down
69 changes: 34 additions & 35 deletionscookbook/form/create_custom_field_type.rst
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -25,6 +25,7 @@ for form fields, which is ``<BundleName>\Form\Type``. Make sure the field extend

use Symfony\Component\Form\AbstractType;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;

class GenderType extends AbstractType
{
Expand All@@ -40,12 +41,7 @@ for form fields, which is ``<BundleName>\Form\Type``. Make sure the field extend

public function getParent()
{
return 'choice';
}

public function getName()
{
return 'gender';
return ChoiceType::class;
}
}

Expand All@@ -54,8 +50,12 @@ for form fields, which is ``<BundleName>\Form\Type``. Make sure the field extend
The location of this file is not important - the ``Form\Type`` directory
is just a convention.

.. versionadded:: 2.8
In 2.8, the ``getName()`` method was removed. Now, fields are always referred
to by their fully-qualified class name.

Here, the return value of the ``getParent`` function indicates that you're
extending the ``choice`` field type. This means that, by default, you inherit
extending the ``ChoiceType`` field. This means that, by default, you inherit
all of the logic and rendering of that field type. To see some of the logic,
check out the `ChoiceType`_ class. There are three methods that are particularly
important:
Expand DownExpand Up@@ -89,24 +89,26 @@ important:
Also, if you need to modify the "view" of any of your child types from
your parent type, use the ``finishView()`` method.

The ``getName()`` method returns an identifier which should be unique in
your application. This is used in various places, such as when customizing
how your form type will be rendered.

The goal of this field was to extend the choice type to enable selection of
a gender. This is achieved by fixing the ``choices`` to a list of possible
genders.

Creating a Template for the Field
---------------------------------

Each field type is rendered by a template fragment, which is determined in
part bythevalueof your``getName()`` method. For more information, see
Each field type is rendered by a template fragment, which is determined in part by
theclass nameof yourtype. For more information, see
:ref:`cookbook-form-customization-form-themes`.

In this case, since the parent field is ``choice``, you don't *need* to do
any work as the custom field type will automatically be rendered like a ``choice``
type. But for the sake of this example, suppose that when your field is "expanded"
.. note::

The first part of the prefix (e.g. ``gender``) comes from the class name
(``GenderType`` -> ``gender``). This can be controlled by overriding ``getBlockPrefix()``
in ``GenderType``.

In this case, since the parent field is ``ChoiceType``, you don't *need* to do
any work as the custom field type will automatically be rendered like a ``ChoiceType``.
But for the sake of this example, suppose that when your field is "expanded"
(i.e. radio buttons or checkboxes, instead of a select field), you want to
always render it in a ``ul`` element. In your form theme template (see above
link for details), create a ``gender_widget`` block to handle this:
Expand DownExpand Up@@ -154,7 +156,7 @@ link for details), create a ``gender_widget`` block to handle this:
.. note::

Make sure the correct widget prefix is used. In this example the name should
be ``gender_widget``, according to the value returned by ``getName``.
be ``gender_widget`` (see :ref:`cookbook-form-customization-form-themes`).
Further, the main config file should point to the custom form template
so that it's used when rendering all forms.

Expand DownExpand Up@@ -241,18 +243,19 @@ new instance of the type in one of your forms::

use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use AppBundle\Form\Type\GenderType;

class AuthorType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('gender_code',newGenderType(), array(
$builder->add('gender_code', GenderType::class, array(
'placeholder' => 'Choose a gender',
));
}
}

But this only works because the ``GenderType()`` is very simple. What if
But this only works because the ``GenderType`` is very simple. What if
the gender codes were stored in configuration or in a database? The next
section explains how more complex field types solve this problem.

Expand DownExpand Up@@ -311,14 +314,14 @@ the ``genders`` parameter value as the first argument to its to-be-created
arguments:
- "%genders%"
tags:
- { name: form.type, alias: gender }
- { name: form.type }

.. code-block:: xml

<!-- src/AppBundle/Resources/config/services.xml -->
<service id="app.form.type.gender" class="AppBundle\Form\Type\GenderType">
<argument>%genders%</argument>
<tag name="form.type"alias="gender"/>
<tag name="form.type" />
</service>

.. code-block:: php
Expand All@@ -331,20 +334,16 @@ the ``genders`` parameter value as the first argument to its to-be-created
'AppBundle\Form\Type\GenderType',
array('%genders%')
))
->addTag('form.type', array(
'alias' => 'gender',
))
->addTag('form.type')
;

.. tip::

Make sure the services file is being imported. See :ref:`service-container-imports-directive`
for details.

Be sure that the ``alias`` attribute of the tag corresponds with the value
returned by the ``getName`` method defined earlier. You'll see the importance
of this in a moment when you use the custom field type. But first, add a ``__construct``
method to ``GenderType``, which receives the gender configuration::
First, add a ``__construct`` method to ``GenderType``, which receives the gender
configuration::

// src/AppBundle/Form/Type/GenderType.php
namespace AppBundle\Form\Type;
Expand DownExpand Up@@ -374,28 +373,28 @@ method to ``GenderType``, which receives the gender configuration::
}

Great! The ``GenderType`` is now fueled by the configuration parameters and
registered as a service. Additionally, because you used the ``form.type`` alias in its
configuration, using the field is now much easier::
registered as a service. Because you used the ``form.type`` alias in its configuration,
your service will be used instead of creating a *new* ``GenderType``. In other words,
your controller *does not need to change*, it still looks like this::

// src/AppBundle/Form/Type/AuthorType.php
namespace AppBundle\Form\Type;

use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;

// ...
use AppBundle\Form\Type\GenderType;

class AuthorType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('gender_code','gender', array(
$builder->add('gender_code',GenderType::class, array(
'placeholder' => 'Choose a gender',
));
}
}

Notice that instead of instantiating a new instance, you can just refer to
it by the alias used in your service configuration, ``gender``. Have fun!
Have fun!

.. _`ChoiceType`: https://github.com/symfony/symfony/blob/master/src/Symfony/Component/Form/Extension/Core/Type/ChoiceType.php
.. _`FieldType`: https://github.com/symfony/symfony/blob/master/src/Symfony/Component/Form/Extension/Core/Type/FieldType.php
Loading

[8]ページ先頭

©2009-2025 Movatter.jp