Chapters
-
Course Code
Subscribe to download the code!Compatible PHP versions: >=5.5.9
Subscribe to download the code!Compatible PHP versions: >=5.5.9
-
This Video
Subscribe to download the video!
Subscribe to download the video!
-
Course Script
Subscribe to download the script!
Subscribe to download the script!
The Form Type Class
Scroll down to the script below, click on any sentence (including terminal blocks) to jump to that spot in the video!
Hey guys! You're back! Awesome! Because this tutorial is all about forms: the good, the bad, and the ugly.
Quit Hatin' on the Forms
The truth is: the form component is super controversial: some people love it, some people hate it - and a lot of people have trouble learning it. In fact, its documentation on symfony.com is read far more than any other section.
Why? Because honestly, it is complex - too complex sometimes. But you know what? The form component is going to allow you to get a lot of work done really quickly. And when I do see someone suffering with forms, most of the time, it's their fault. They create situations that are far more complicated than they need to be.
So let's not do that - let's enjoy forms, and turn them into a weapon.
Sing Along Code along!
Ok, you guys know the drill: download the course code and unzip it to code along
with me. Inside, you'll find the answers to life's questions and a start/ directory
that has the same code I have here. Make sure to check out the README for all the
setup details.
Once you're ready, start the built-in web server with:
./bin/console server:run
I made a few changes to the site since last time. For example, go to localhost:8000/genus.
It looks the same, but see the "Sub Family"? Before, that was a string field
on Genus. But now, I've added a SubFamily entity:
|
Show Lines
|
// ... lines 1 - 6 |
| /** | |
| * @ORM\Entity | |
| * @ORM\Table(name="sub_family") | |
| */ | |
| class SubFamily | |
| { | |
| /** | |
| * @ORM\Id | |
| * @ORM\GeneratedValue(strategy="AUTO") | |
| * @ORM\Column(type="integer") | |
| */ | |
| private $id; | |
| /** | |
| * @ORM\Column(type="string") | |
| */ | |
| private $name; | |
|
Show Lines
|
// ... lines 24 - 38 |
| } |
And created a ManyToOne relation from Genus to SubFamily:
|
Show Lines
|
// ... lines 1 - 11 |
| class Genus | |
| { | |
|
Show Lines
|
// ... lines 14 - 25 |
| /** | |
| * @ORM\ManyToOne(targetEntity="AppBundle\Entity\SubFamily") | |
| * @ORM\JoinColumn(nullable=false) | |
| */ | |
| private $subFamily; | |
|
Show Lines
|
// ... lines 31 - 117 |
| } |
So every Genus belongs to one SubFamily.
I also started a new admin section - see it at /admin/genus. But, it needs some
work - like the ability to add a new genus. That'll be our job. And the code will
live in the new GenusAdminController.
Creating a new Form
To create a form, you'll add a class where you'll describe what the form looks like.
Tip
Actually, you can build a form directly in the controller if you want to.
In PhpStorm, select anywhere in your bundle and press command+N, or right click
and select "New". Find "Form" and call it GenusFormType:
|
Show Lines
|
// ... lines 1 - 2 |
| namespace AppBundle\Form; | |
| use Symfony\Component\Form\AbstractType; | |
| use Symfony\Component\Form\FormBuilderInterface; | |
| use Symfony\Component\OptionsResolver\OptionsResolver; | |
| class GenusFormType extends AbstractType | |
| { | |
| public function buildForm(FormBuilderInterface $builder, array $options) | |
| { | |
| } | |
| public function configureOptions(OptionsResolver $resolver) | |
| { | |
| } | |
| } |
Cool! This just gave us a basic skeleton and put the class in a Form directory. Sensible!
These classes are called "form types"... which is the worst name that we could come
up with when the system was created. Sorry. Really, these classes are "form recipes".
Here's how it works: in buildForm(): start adding fields: $builder->add() and
then name to create a "name" field:
|
Show Lines
|
// ... lines 1 - 8 |
| class GenusFormType extends AbstractType | |
| { | |
| public function buildForm(FormBuilderInterface $builder, array $options) | |
| { | |
| $builder | |
| ->add('name') | |
|
Show Lines
|
// ... lines 15 - 16 |
| ; | |
| } | |
|
Show Lines
|
// ... lines 19 - 23 |
| } |
Keep going: add('speciesCount') and add('funFact'):
|
Show Lines
|
// ... lines 1 - 12 |
| $builder | |
| ->add('name') | |
| ->add('speciesCount') | |
| ->add('funFact') | |
| ; | |
|
Show Lines
|
// ... lines 18 - 25 |
Right now, those field names can be anything - you'll see why in a second.
And that's it! The form is built after writing about 4 lines of code! Let's go render it!
80 Comments
"Houston: no signs of life"
Start the conversation!
What PHP libraries does this tutorial use?
// composer.json
{
"require": {
"php": ">=5.5.9",
"symfony/symfony": "3.1.*", // v3.1.4
"doctrine/orm": "^2.5", // v2.7.2
"doctrine/doctrine-bundle": "^1.6", // 1.6.4
"doctrine/doctrine-cache-bundle": "^1.2", // 1.3.0
"symfony/swiftmailer-bundle": "^2.3", // v2.3.11
"symfony/monolog-bundle": "^2.8", // 2.11.1
"symfony/polyfill-apcu": "^1.0", // v1.2.0
"sensio/distribution-bundle": "^5.0", // v5.0.22
"sensio/framework-extra-bundle": "^3.0.2", // v3.0.16
"incenteev/composer-parameter-handler": "^2.0", // v2.1.2
"composer/package-versions-deprecated": "^1.11", // 1.11.99
"knplabs/knp-markdown-bundle": "^1.4", // 1.4.2
"doctrine/doctrine-migrations-bundle": "^1.1" // 1.1.1
},
"require-dev": {
"sensio/generator-bundle": "^3.0", // v3.0.7
"symfony/phpunit-bridge": "^3.0", // v3.1.3
"nelmio/alice": "^2.1", // 2.1.4
"doctrine/doctrine-fixtures-bundle": "^2.3" // 2.3.0
}
}