Chapters
32 Chapters
|
4:16:27
|
Login to bookmark this video
-
Course Code
Subscribe to download the code!
Subscribe to download the code!
-
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!
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": ">=8.2",
"ext-ctype": "*",
"ext-iconv": "*",
"babdev/pagerfanta-bundle": "4.x-dev", // 4.x-dev
"doctrine/doctrine-bundle": "^2.10", // 2.12.x-dev
"doctrine/doctrine-migrations-bundle": "^3.2", // 3.4.x-dev
"doctrine/orm": "^2.16", // 2.18.x-dev
"knplabs/knp-time-bundle": "dev-main", // dev-main
"pagerfanta/doctrine-orm-adapter": "4.x-dev", // 4.x-dev
"pagerfanta/twig": "4.x-dev", // 4.x-dev
"symfony/asset": "6.4.*", // 6.4.x-dev
"symfony/asset-mapper": "6.4.*", // 6.4.x-dev
"symfony/console": "6.4.x-dev", // 6.4.x-dev
"symfony/dotenv": "6.4.x-dev", // 6.4.x-dev
"symfony/flex": "^2", // 2.x-dev
"symfony/form": "6.4.x-dev", // 6.4.x-dev
"symfony/framework-bundle": "6.4.x-dev", // 6.4.x-dev
"symfony/monolog-bundle": "^3.0", // dev-master
"symfony/runtime": "6.4.x-dev", // 6.4.x-dev
"symfony/security-csrf": "6.4.x-dev", // 6.4.x-dev
"symfony/stimulus-bundle": "2.x-dev", // 2.x-dev
"symfony/twig-bundle": "6.4.x-dev", // 6.4.x-dev
"symfony/ux-autocomplete": "2.x-dev", // 2.x-dev
"symfony/ux-live-component": "2.x-dev", // 2.x-dev
"symfony/ux-turbo": "2.x-dev", // 2.x-dev
"symfony/ux-twig-component": "2.x-dev", // 2.x-dev
"symfony/validator": "6.4.x-dev", // 6.4.x-dev
"symfony/web-link": "6.4.*", // 6.4.x-dev
"symfony/yaml": "6.4.x-dev", // 6.4.x-dev
"symfonycasts/dynamic-forms": "dev-main", // dev-main
"symfonycasts/tailwind-bundle": "dev-main", // dev-main
"tales-from-a-dev/flowbite-bundle": "dev-main", // dev-main
"twig/extra-bundle": "^2.12|^3.0", // 3.x-dev
"twig/twig": "^2.12|^3.0" // 3.x-dev
},
"require-dev": {
"doctrine/doctrine-fixtures-bundle": "^3.4", // 3.6.x-dev
"phpunit/phpunit": "^9.5", // 9.6.x-dev
"symfony/browser-kit": "6.4.*", // 6.4.x-dev
"symfony/css-selector": "6.4.*", // 6.4.x-dev
"symfony/debug-bundle": "6.4.x-dev", // 6.4.x-dev
"symfony/maker-bundle": "^1.51", // dev-main
"symfony/panther": "^2.1", // v2.1.1
"symfony/phpunit-bridge": "7.1.x-dev", // 7.1.x-dev
"symfony/stopwatch": "6.4.x-dev", // 6.4.x-dev
"symfony/web-profiler-bundle": "6.4.x-dev", // 6.4.x-dev
"zenstruck/browser": "1.x-dev", // 1.x-dev
"zenstruck/foundry": "^1.36" // 1.x-dev
}
}
What JavaScript libraries does this tutorial use?
// importmap.php
return [
'app' => [
'path' => './assets/app.js',
'entrypoint' => true,
],
'js-confetti' => [
'version' => '0.11.0',
],
'@hotwired/stimulus' => [
'version' => '3.2.2',
],
'@symfony/stimulus-bundle' => [
'path' => './vendor/symfony/stimulus-bundle/assets/dist/loader.js',
],
'tom-select' => [
'version' => '2.3.1',
],
'tom-select/dist/css/tom-select.default.css' => [
'version' => '2.3.1',
'type' => 'css',
],
'@hotwired/turbo' => [
'version' => '7.3.0',
],
'stimulus-popover' => [
'version' => '6.2.0',
],
'debounce' => [
'version' => '1.2.1',
],
'turbo-view-transitions' => [
'version' => '0.3.0',
],
'stimulus-use' => [
'version' => '0.52.1',
],
'flowbite' => [
'version' => '2.2.1',
],
'@popperjs/core' => [
'version' => '2.11.8',
],
'flowbite-datepicker' => [
'version' => '1.2.6',
],
];
15 Comments
Has the bug mentioned at 9:25 been resolved? That use case is exactly what I'm currently trying to achieve and could have used some guidance.
Hi @Seriousedy
Sorry for the late answer, as I see from git updates, that should be already fixed in
symfony/ux-autocompletepackage, however, we are not applying such fixed to course code. So it's up to you to test it 😉Cheers1
Hey Ryan. Thanks again for another great tutorial. I just updated an app with a lot of form events, Ajax calls, and custom stimulus controllers, because of many dependent form fields and many kind of complex CollectionType fields.
Now I got rid of a lot of boilerplate code, and I am very happy to use LiveComponents more in the future.
For me, as a more backend-focused full-stack developer, it is a very nice technology. And now we even got to choose between multiple technologies that do in this direction (live-components, turbo, htmx as the most prominent ones).
I am just left with one question.
I am using live-components in combination with "SymfonyCasts/dynamic-forms" and it works perfect. But with my old custom setup, I knew exactly when I dynamically added dependent form fields or added/removed new items of a CollectionType, and in these cases manually added css classes to animate the newly added items/rows, so that it is smoother from a ux perspective.
How can I react to new dependent rows/fields of my form that get added or removed, or the same for items of my LiveCollection?
I know (from the awesome docs) there are hooks like "render:finished" which I am already using to get the Trix editor working with live components, but I am not sure what is the best ans most easy way to detect newly added or removed items and to add my css classes to those. Any ideas?
Hey @TristanoMilano
Happy to hear about the stack you are using. That is a proof that we are working in the right direction! About your question, I think this section of docs should help you https://symfony.com/bundles/ux-live-component/current/index.html#javascript-component-hooks. espesially
loading.state:hooks, give a try =)Cheers!
Hi everyone, a great tool for dependent form fields - I'm thrilled :)
I have the problem that dependent fields are no longer recognized as mandatory fields. I work with Turbo and LiveComponents. Displaying and hiding the dependent fields works wonderfully. But the "new" dependent fields are not recognized as mandatory fields if they are displayed.
Is there a solution?
thank you so much! cheers :)
Hey @creativx007!
Sorry for the slow reply: the team kept this message for me and I've been missing!
Hmm. This "should" just come down to validation. I'd use the
Callbackconstraint: https://symfony.com/doc/current/reference/constraints/Callback.html. This would allow you to mark certain fields asNotBlankIF some other field has a certain value.Way late, but I hope this helps you or someone else.
Cheers!
Hello people form SC! I have a question on Real Time validation with Live Components. I have a form and validation is going ok. But as soon as i add a field with the DateType::class i get an error. The error occurs when i fill in an other field. But I expect that the DateTime field doesn't throw an error because i didn't changed it yet.
I tried to change the DateType field to the default values but the error keeps popping. It doesn't happen on the other required fields (nullable=false in the entity class).
The formbuilder:
The fields in the entity class:
The error:
Hey @lexhartman!
I think you're close to the solution :). In this case, the error isn't really a validation error: it's a PHP error. When the
executedAtfield is submitted empty, it's converted tonulland the form system tries to call$yourObject->setExecutedAt(null). This happens even before validation is executed. I can see that your$executedAtproperty does allownull. But is it possible that yoursetExecutedAt()method does not allownull? It should look like this:Let me know if this was the issue :).
Cheers!
Yes! That was it 😅
Hi Ryan, I have a quick question on Real Time validation.
My form has a field which is a LiveCollectionType. I copied your example from the symfony ux demo page, and it works awesomely. However I'm having one weird issue with real time validation.
The validation on the embedded form type works perfectly, exactly how I would expect. However on the actual collection type, I have a constraint with a
new Count(min: 1). Now, if I remove the last embedded object from the collection (or don't add any in the first place), I don't get any real time validation on this field. I can live with that, because when I post the form I will get the error displayed then. When I add to the collection, the error goes away in real time. Perfect!But here's my issue. When this form has been posted (with zero in the collection causing the error), and now I press the 'add to collection' button, as I said the error will go away, however the embedded form is validating straight away, and since the field inside the collection is currently empty, I am getting the validation error. I would expect to NOT see a validation error until the user types something, deletes it, then tabs away. Every new embedded form added to the collection will have this issue, until the entire page is reloaded.
Did I miss something obvious?
Yo @Scott-D!
Sorry my slow reply! First, I don't use
LiveCollectionTypepersonally, so my knowledge is a bit limited. I really need to play with it more just so I can speak about it and, possibly, improve it if needed.Does this problem only happen if the entire form has been posted with zero items? Or does it happen after you submit the form in general (i.e. even if you have 2 items in the collection, after submitting, you will see the problem when you add a 3rd item)? Are you submitting via a
LiveAction?A key to making the auto-validation work is that LiveComponents keeps track of which fields have been modified by the user. Then, when you submit, it's careful to remove any errors from fields that have not yet been touched by the user. Otherwise, EVERY field would be validated the first time the live component re-renders, even though the user has only completed one field. There is even a
LivePropthat tracks which fields have been modified - https://github.com/symfony/ux/blob/2.x/src/LiveComponent/src/ComponentWithFormTrait.php#L63However, when you submit the form, now you want EVERY field to be validated. In this case, we stop keeping track of
validatedFieldsand instead mark the entire form as needing validation. You can see that here - https://github.com/symfony/ux/blob/2.x/src/LiveComponent/src/ComponentWithFormTrait.php#L88-L91 and here https://github.com/symfony/ux/blob/2.x/src/LiveComponent/src/ComponentWithFormTrait.php#L158-L163 (depending on if you're submitting your form via a normal controller vs a LiveAction).So I think that's what's happening. You're submitting your form, so
isValidatedbecomes true and every field going forward is validated. I don't have an exact solution for you, but given this info, there may be a workaround you can do (and perhaps that workaround should be in the core library itself). For example, you may, before rendering (e.g. via a PreRender hook), grab your form object and manually clear the errors for any collection fields that look blank to you (see https://github.com/symfony/ux/blob/2.x/src/LiveComponent/src/ComponentWithFormTrait.php#L271-L280 for some info on how you can clear an error).Let me know if that helps!
Cheers!
Hey Ryan, Thanks for such a detailed response!
Only in the first case. The 2nd case works perfectly, exactly as I would expect. If I edit an existing resource that has two items, then go to add a 3rd, there will be no immediate validation on that new embedded form.
So to reproduce:
As soon as I type into the required fields and tab away, those errors will go away in real time.
No, I'm not. I pretty much followed your example here to a T. In fact, I didn't even know about
LiveAction. I will definitely take a closer look at that.Thanks Ryan, I'll give this a shot!
Ryan,
I have these fields:
All works really well on a new form, but when I render the form for an 'edit', these three fields don't have their initial data. All my other form fields do, but not these three. So one would have to re-select these fields on an edit, even if they don't want to change them. I can not figure out why, any suggestions?
Yo @Brandon!
Hmm, interesting. This video also shows an edit form: and both of the fields DO have their value. What's interesting to me is this:
The key parts is: three fields. If truly all 3 fields are missing their data, that's significant because the first field -
selectedCategory- is not a dependent field: this is a plain, boring, normal field. So if this is empty on edit, double-check that the underlying data is, in fact set. This may not be a problem with the dynamic forms at all.Cheers!
Ryan,
I made an oversight, I wasn't saving the selectedCategory in the database, and I had no code to reverse back to it from the selectedGroup. Thank you for all your help, I wish you all the best. You have helped me so much in my journey.
"Houston: no signs of life"
Start the conversation!