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!
06.
DateTimeType & Data "Transforming"
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
}
}
23 Comments
I have a project (Symfony 6.0.4 ) with a form bound to an entity that has a date field. Symfony is guessing Date (correctly, of course) and I am using the
widget => single_textoption to render the field as an HTML5 date input. When I select a date with my browser's datepicker and submit, and the POSTed value is something like "2022-02-24", I get the validation error "This value should be of type string." Any idea why? It certainly <i>is</i> a string.In the form class I am saying: $builder->add('date',DateType::class, ['widget'=>'single_text','empty_data'=>''])
In the underlying entity:
Hey David,
Hm, usually it might be invalid date format, because browser's widget may pass date's day/month/year in an incorrect order that your server expects, but I suppose you get "a valid date is required" message instead, so probably it's not the reason here. It's difficult to say without some debugging. Please, try to dump some things, i.e. dump the form data you're going to process on post request. Probably, the field is actually empty because you forget to add "name" attribute to it, or the form has another field with the same name that overwrites your date value with an empty string, etc.
Also, I'm not sure about that "empty_data => null" in your form type, could you comment it out and try again? It might be the reason btw.
But, in general I'd not use Browser's built-in datetime picker and try a JS library instead.
I hope this helps!
Hi. Thank you for the advice. When I look at the Profiler's Validator Calls, the date field's invalid value is indeed a DateTime object. When I look at the $_POST parameters in the Profiler, it's "date'" => "2022-02-15" as it should be. The Firefox console shows the same thing.
I changed the field type to TextType; attached a CallbackTransformer to convert between string and DateTime; and tried manually entering "2022-02-15". The result was that I still get the same validation error message "This value should be of type string." I tried commenting out the data-transformation bit, and the result is 'Expected argument of type "?DateTimeInterface", "string" given at property path "date".' -- which would make sense, were it not for the fact that this is failng either way.
I also removed
['empty_data'=>'']but that made no difference....<b>UPDATE!</b>
I changed the form field back to native HTML5 Date type, but removed the
@Assert\Datefrom the entity class -- <i>and that made the issue go away!</i> Going back to the <a href="https://symfony.com/doc/current/reference/constraints/Date.html">docs</a>, I finally understand. That constraint is for <i>strings</i>! So when it was getting a DateTime it was rightly complaining that it wasn't getting a string! Agh. Sometimes it's telling you the simple truth as plainly as can be, and it still takes a couple hours to understand :-) Silly mistake, made harder to track down because it wasn't displaying the custom error message I had configured.Hey David,
Ah, I see now! :) Yeah, a really tricky case that easily misunderstood, I'm happy you were able to track it down and figured out the problem yourself, well done! And thanks for sharing the final solution!
Cheers!
I have a form with an email field of type EmailType::class, but when I submit the form, $form->isValid() returns true even if the value of the email field is not a valid email address (no "@"). How come?
Hey Matteo S.
Having email field has nothing with validation, you should add validation constraints to the form or to the entity property. You will learn more about validation on chapter 10 of this course =)
Cheers!
isValid() has nothing to do with validation?? If I add a field of IntegerType, it gets validated automatically (if I submit a non-numeric string isValid() returns false and I get an error message in the form widget), but if I add a field of EmailType type, it is not? How does that make sense? See my full example code here: https://github.com/symfony/...
The message you got with IntegerType is more core type validation, because value should be bound to Integer type property, and you got string, that's why it fails, but email field is bound to simple String and it is a valid string. To have proper validation you should have constraints configured in your form or entity, for example
BTW you should have
symfony/validatorinstalledCheers!
Using Symfony/Forms 4.4. When I tried to add widget as an option I get an error saying that widget is not an option that is available. Did I miss something when I did the composer require that makes this an option?
Hey captsulu32
What FormFieldType are you using?
Cheers!
`
->add('ssn', null,
`
As you can see null
Ok, so you're letting the TypeGuesser sytem to guess the Type of your "ssn" field. Try specifying a Date or DateTime type instead.
<b>Goal:</b>
I need a field "time spent to write an article".
The form does have two fields, hours and minutes.
But the hours can exceed 24, so it is possible that the user enters 99 hours and 59 minutes.
Since TimeType cant do this and DateTimeType (like in this tutorial) seems to be like a "hacky solution", I chose DateIntervalType (I think this is best practise?).
My form:
This field is 100% optional, but should NOT be prefilled with 00:00 on the front end (which would work), because the field is easier to "forget" if its prefilled on the front end.
So on the front end, it should be empty unless the user typed something in.
<b>Problem:</b>
Even if I set required = false, I get an transformation failed exception if the two fields (hours & minutes) are empty:
I've found the solution!
Instead of:
'widget' => 'integer', // render a text field for each part
I need to use:
'widget' => 'text', // render a text field for each part
SF seems to be pretty "type strict", meaning if I set "integer", it really wants an integer every time, "" (empty string) is not accepted.
Yet I don't understand exactly, what "text" can do / accepts, what "integer" can't. (Despite the "text" allows an empty string)
Hey Mike P.
I'm glad that you could find a solution. Regarding to your question, the only difference I can tell between text and integer type is the input field that will be rendered. You can read more about it in the docs: https://symfony.com/doc/cur...
Cheers!
If we do not set a type and leave it for guessing, does it slows down performance on each page load, or it is cached and so only on cache build?
Hey Lijana Z.!
Wow, really great question! It's honestly not something I had thought about :). From checking out the code, I don't see any evidence of this stuff being cached. Here is the method that is responsible for all this "guessing: (and, like I said, it looks like the code that calls this does not include any caching): https://github.com/symfony/...
I'll say 2 things about this:
1) The "guessers" themselves often *do* contain caching. For example, Doctrine metadata is cached - so checking whether or not a column is "nullable=false" is nearly instant. Or, the property-info component, which is responsible for looking at a class to determine if a property is mutable (e.g. does it have a setter? is it public? does it have a constructor arg?) also caches its metadata. So while the system overall isn't cached, the guessers *do* tend to have caching.
2) I've never profiled this guessing vs not-using-guessing directly, but I've never seen (while using Blackfire.io) that the guessing system took any amount of significant performance. If I was worried, that's what I would check: profile your form load with Blackfire and see if it's *really* a problem. We have a free screencast on Blackfire... which is fun anyways ;) https://symfonycasts.com/sc...
Cheers!
Actually Chrome Browser renders a Text Field instead of the expected Date and Time dropdowns if set no type and options.
Version 78.0.3904.108 (November 2019)
Hey Maik,
Hm, this sounds like Symfony was not able to guess the field type correctly, that's why it renders text field instead of date field. It might depends on your mapping configuration for that field in your entity I think.
Cheers!
Warning, Mozilia does not support the calendar widget.
https://developer.mozilla.o...
Hey Virgile,
Thank you for this warning. Yeah, Firefox is the browser that does not support it on desktops... though probably it does on mobiles. Anyway, to support it well, it's still better to use a JS library for it.
Cheers!
I have done something a little bit advanced compared to the tutorial, but I have a problem with that, the idea is ok but actually doens't work.
I have build a FilterFrom that I'll use to filter my articles, and is built like that:
`public function buildForm(FormBuilderInterface $builder, array $options)
I want to use datatimepicker7-8 which are the one who are linked one to another so you can select a interval between 2 dates, the template look like this:
`
I tried to adjust everything in a way that could work, but I get the error:
An exception has been thrown during the rendering of a template ("Notice: Array to string conversion") in "bootstrap_4_layout.html.twig".
Js:
`
<script src={{ asset('js/moment.js') }}></script>
`
Can you help me?
P.S: I'm not using encore
Hey Gballocc7
Something inside
bootstrap_4_layout.html.twigis trying to print an array (it should be a string). I believe it comes from yourtagfield. Try removing it just to be sure that's the problem and if that's the problem, check your repository method, in what form is it returning the data?Cheers!
"Houston: no signs of life"
Start the conversation!