Chapters
41 Chapters
|
4:45:40
|
Login to bookmark this video
-
Course Code
Subscribe to download the code!Compatible PHP versions: ^7.1.3
Subscribe to download the code!Compatible PHP versions: ^7.1.3
-
This Video
Subscribe to download the video!
Subscribe to download the video!
-
Subtitles
Subscribe to download the subtitles!
Subscribe to download the subtitles!
-
Course Script
Subscribe to download the script!
Subscribe to download the script!
31.
Form Type Extension
Scroll down to the script below, click on any sentence (including terminal blocks) to jump to that spot in the video!
Subscribe to jump to this part in the video!
Keep on Learning!
If you liked what you've learned so far, dive in! Subscribe to get access to this tutorial plus video, code and script downloads.
What PHP libraries does this tutorial use?
// composer.json
{
"require": {
"php": "^7.1.3",
"ext-iconv": "*",
"composer/package-versions-deprecated": "^1.11", // 1.11.99
"doctrine/annotations": "^1.0", // 1.10.2
"doctrine/doctrine-bundle": "^1.6.10", // 1.10.2
"doctrine/doctrine-migrations-bundle": "^1.3|^2.0", // v2.0.0
"doctrine/orm": "^2.5.11", // v2.7.2
"knplabs/knp-markdown-bundle": "^1.7", // 1.7.0
"knplabs/knp-paginator-bundle": "^2.7", // v2.8.0
"knplabs/knp-time-bundle": "^1.8", // 1.8.0
"nexylan/slack-bundle": "^2.0,<2.2.0", // v2.0.0
"php-http/guzzle6-adapter": "^1.1", // v1.1.1
"phpdocumentor/reflection-docblock": "^3.0|^4.0", // 4.3.0
"sensio/framework-extra-bundle": "^5.1", // v5.2.1
"stof/doctrine-extensions-bundle": "^1.3", // v1.3.0
"symfony/asset": "^4.0", // v4.1.6
"symfony/cache": "^3.3|^4.0", // v4.1.6
"symfony/console": "^4.0", // v4.1.6
"symfony/flex": "^1.0", // v1.21.6
"symfony/form": "^4.0", // v4.1.6
"symfony/framework-bundle": "^4.0", // v4.1.6
"symfony/property-access": "^3.3|^4.0", // v4.1.6
"symfony/property-info": "^3.3|^4.0", // v4.1.6
"symfony/security-bundle": "^4.0", // v4.1.6
"symfony/serializer": "^3.3|^4.0", // v4.1.6
"symfony/twig-bundle": "^4.0", // v4.1.6
"symfony/validator": "^4.0", // v4.1.6
"symfony/web-server-bundle": "^4.0", // v4.1.6
"symfony/yaml": "^4.0", // v4.1.6
"twig/extensions": "^1.5" // v1.5.2
},
"require-dev": {
"doctrine/doctrine-fixtures-bundle": "^3.0", // 3.0.2
"easycorp/easy-log-handler": "^1.0.2", // v1.0.7
"fzaninotto/faker": "^1.7", // v1.8.0
"symfony/debug-bundle": "^3.3|^4.0", // v4.1.6
"symfony/dotenv": "^4.0", // v4.1.6
"symfony/maker-bundle": "^1.0", // v1.8.0
"symfony/monolog-bundle": "^3.0", // v3.3.0
"symfony/phpunit-bridge": "^3.3|^4.0", // v4.1.6
"symfony/stopwatch": "^3.3|^4.0", // v4.1.6
"symfony/var-dumper": "^3.3|^4.0", // v4.1.6
"symfony/web-profiler-bundle": "^3.3|^4.0" // v4.1.6
}
}
20 Comments
For 4.3+ versions of Symfony..
Also, <b>do not</b> copy this code from the scripts page under the "Tip" section, as it has a typo..
<i>Notice the 't' in getExten<b>t</b>edTypes()</i>
Hey Adam!
Ah, great catch! Thank you for reporting it! It was fixed in: https://github.com/knpunive... , so now people may copy code from the Tip :)
Cheers!
Are there really no other way to add new option besides creating extension type? It looks way too much work for such simple thing. I have got error "The option "x" does not exist." many times and it was really wtf moments - I used to end up to find some different solution but not creating an extension class.
If there is no other way, do you know why it is made that way? What is the point of this? If so I wish the error message would be more helpful - by telling how to solve - to create a form extension and give a link to the documentation or this tutorial for example. It would same so much time for many developers. There are lot of stack overflow questions, so it really shows there is a big problem. I saw SO question from 2015 so 4-5 years and nobody said to create a form extension over so much time.
After watching next video - I saw you are inventing new option without creating an extension. So looks like there is a way, but now I guess the reason we here needed an extension is that because the TextAreaFormType is vendor class which we cannot modify.
Yo Lijana Z.!
Excellent question. The answer is.... it depends on what you are trying to do ;). Let's look at the error:
There are 3 different situations where you might get this error:
A) You might get this error if you simply have a "typo" on an option name - e.g. you use
requuredinstead ofrequired. In that case, you definitely don't want to create a form type extension - you just want to fix your typo. That's something I like a lot about the "options" system: you can't typo something and have it "silently" fail: you will get a clear error that the option does not exist.B) You might get this error in a situation where you are trying to pass a custom option to a "form type" class that you created. For example, suppose you have a "RegistrationFormType" that you use in 2 different pages on your site. On one page, you DO want a "subscribe to newsletter" checkbox but on another screen (for some reason) you want the same form but without that checkbox. One way to do that is to "invent" a new option that you pass when creating your RegistrationFormType in the controller - e.g.
'with_newsletter' => true. In this case, you are "inventing" an option. But you do not need a form type extension if you just want to add an option to one form type (and also if that form type is your class). Instead, you create the option by adding it to theconfigureOptionssection of your RegistrationFormType.C) You might get this error in a situation where you are trying to pass a custom option to a "field" that you did not create - e.g. TextareaType. OR because you want to be able to pass an option to any (or at least many) different fields. This is where you need a form type extension: because you want to add a custom option to a form field that you did not create (something in vendor/) or because you want to add a custom option to many/all form fields in your system.
Creating a form type extension is really a pretty rare thing to need to do - it's very powerful, but it's not that common that you need to add a custom option to a vendor "type" or to "all" types. The options system in general can be a confusing, so let me know if this helps... or just make things more confusing ;).
Cheers!
Thanks, it helps. I hope those videos and comments will not be gone while symfony will be used just in case I need to read/watch again :)
Hi,
I have this error after developing the TextareaSizeExtension class and configuration the services.yaml file:
How can I solve that please?
Hey @stephansav!
Hmm. My guess is that you may have an indentation problem in your services.yaml file. Any extra (or missing) indentation will have a different "meaning" when it's parsed - so look very closely at your indentation levels and compare them with mine :). For example, I think you might have a
-that is maybe only indented 2 or 4 spaces from the root of the file (so 2 or 4 spaces in total) and this is looking like an array with a "0" index under "services" to Symfony.Let me know if that helps!
Cheers!
Hi,
I checked what you told me and there is no problem with the indentation in services.yaml. Here my code:
How can I solve that?
Hey @stephansav!
Ah, thanks for posting this! I mis-read the error completely! I think you might be missing a "use" statement for the TextareaType inside your TextareaSizeExtension. Let me know if that's it :).
Cheers!
Hi,
that's it. Thank you very much! :)
Hello
I am using 4.3
i extended the example and tried to play around:
to disable ALL fields (just for testing)
public function buildView(FormView $view, FormInterface $form, array $options)
{
$view->vars['attr']['rows'] = 10;
$view->vars['attr']['disabled'] = true;
}
public static function getExtendedTypes() :iterable
{
return [
FormType::class,
TextareaType::class
];
}
I expected all fields to be disabled and have a rows attribute set to 10
But only the textarea had rows=10 and the disabled attribute set
When I CHANGED the NAME of the class (and corresponding the name of the file for autoloader) from TextareaSizeExtension (like in the example) to something else: BlubbiSizeExtension.
It worked!
There must be some very weird "magic" in symfony which detects from the NAME of the class, what i COULD HAVE meant and blocks everything else.
Just in case, someone else wants to add something to an extension.
Dont use the class name given in the examples.
IF u use the name: TextareaSizeExtension, nothing else will work. Only textarea-related things.
Greetings
Chris
Hey Christoph
That's odd, it should have detected your extension, the name of the file (IIRC) doesn't do anything. Symfony calls the
getExtendedTypesmethod in order to detect on which field types the extension should be applied. I think you just had to clear your cache. If you rename the extension to its original name, does the problem re-appears?Cheers!
I'm afraid everything you said about 4.2 does NOT hold true on my 4.2.1 installation.
Setting getExtendedAreaType to static and adding the "s" on the end gave this area:
FatalErrorException<br />Error: Class App\Form\TypeExtension\TextareaSizeExtension contains 1 abstract method and must therefore be declared abstract or implement the remaining methods (Symfony\Component\Form\FormTypeExtensionInterface::getExtendedType)After changing it back to the way it was, I got this error:
InvalidArgumentException<br />"form.type_extension" tagged services have to implement the static getExtendedTypes() method. The class for service "App\Form\TypeExtension\TextareaSizeExtension" does not implement it.After adding the config bit in services.yaml that you explicitly say isn't necessary, all errors go away. Am I missing something?
Hey @Aaron!
Hmm, I think our description of this might be inaccurate indeed. Because, in this video, we're implementing the interface directly, I believe you will need both methods until Symfony 5. However, the
getExtendedTypeshould not actually be called anymore - you need to have it to make the interface happy, but it can be blank. If you implement thepublic static function getExtendedTypes()method, then you should not need the config.So, have both methods, leave
getExtendedTypeblank, and add the new "s" version (as static). Then you should not need the config.Sorry about the confusion!
Cheers!
There is a type inside the code block of this page: As you said, getExtendedTypes() as to be declared as a public static function. On SymfonyCast it is declared just as public function. "static" is missing on the code block
Hey Mike,
Thank you for reporting it! getExtendedTypes() really should be declared as "public *static* function". We'll fix it soon in the tutorial.
Cheers!
Hello Ryan,
After implement all the method, I have warning of PhpStorm about getExtendedTypes method.
I read on interface FormTypeExtensionInterface that public function getExtendedType() has @deprecated since Symfony 4.2.
Finally, leaving the configurations in the services.yaml file the form type extension works but if I delete the configurations there is error.
Can you enlighten me. Thank in advance.
Hey Stephane
Thanks for highlighting this new change. Have you tried to implement
getExtendedTypesmethod (notice an ending S on the method name) and then remove the configuration? I believe it should workCheers!
Hey Diego,
This solution does not work on Symfony 4.2.1, it only works when we code as if we are using Symfony 4.1 in a Symfony 4.2.1 environment. Is there a reason for this?
////UPDATE --> 15Min Later...\\\
The caveat here is that the static function "getExtendedTypes" (yes I noticed the 'S' at the end) should be returning an Array.
SO for everyone who is running into trouble with this part here is the complete code:
vars['attr']['rows'] = 3;
}
public function finishView(FormView $view, FormInterface $form, array $options)
{
}
public function configureOptions(OptionsResolver $resolver)
{
}
public function getExtendedType()
{
}
public static function getExtendedTypes()
{
return [TextareaType::class];
}
}
Oh, yes, you are totally right. I forgot to mention that it must return an array (or been more precise, an iterable) now
Cheers!
"Houston: no signs of life"
Start the conversation!