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
Hi,
Thanks for the tutorial! :)
I believe there’s an issue with the recent update regarding async CSRF. Since I’m using the StimulusBundle Flex recipe, I’m encountering problems with the new csrf_protection_controller.js. Now, every form inside a Turbo modal stops working (even though it works fine with a regular request outside the modal).
The issue might stem from the
document.addEventListener('submit', function (event) { … })found in the controller. This event never gets triggered when using the modal, as described in the tutorial. I suspect it could be something related to the modal Stimulus controller of the tuto, but I can’t figure out what exactly.hey @sylvaindeloux
yeah, that's pretty weird, but I'd recommend disabling stateless csrf the code here is not configured to use it, so it causes issues, and the problem is not in this controller, but in new
csrf.yamlwhere stateless csrf is configured. To solve issue just disable it.Cheers!
Looks like this can be fixed by removing / stimulusFetch: 'lazy' / from the csrf_protection_controller.js
https://github.com/symfony/symfony/issues/59571#issuecomment-2610555055
Thanks for the tip
Hello !
I'm having a really weird issue and I found nothing about it in the Symfony UX or the Turbo documentation, GitHub repos or internet at all.
I have CSRF protection enabled on my website and when sumitting the form in the turbo frame I have a form validation error "Invalid CSRF Token" and this log "CSRF validation failed: double-submit info was used in a previous request but is now missing.''
The form is working perfectly on the dedicated page, but inside a frame this happen. Also the form in the frame works again for a short period when deleting the PHPSESSID cookie.
Is there something to know about turbo frame and submitting form with CSRF protection ? Or should I write an issue in symfony UX or turbo in GitHub ?
Hey Hugo,
As a workaround, you can just turn off the CSRF protection for some forms that are handled in turbo frames. Yeah, CSRF may indeed cause some issues in some cases, especially when we're talking about async requests.
But actually, even with Turbo frames it should work well I think, though probably you have a more complex setup? Maybe the problem in Turbo drive cache. You should try to find steps to reproduce. When you will have them, and when you will be 100% sure that following those steps you will get the issue with CSRF protection - analyze the steps to see the problem, I bet it will be more obvious to see the problem and a possible fixes when you take a look at the steps to reproduce.
I hope that helps!
Cheers!
Hi, I'm confusing about "loadingContent" and "loadingTemplate".
For example, I read: "Over in the modal controller, add a new target called loadingContent:" but in the code the target is "loadingTemplate".
Also in other parts of tutorial there are these little mistakes... or am I missing something?
Hey @Fedale
Thanks for reporting it. Indeed this is a little mistake. I'll look for a way to make it right
Cheers!
Hi Ryan,
Cool stuff, really! I do however have a question, I have implemented the ajax modal and use the openModal way so we have the out-of-the-box escape close handler. I also have the stimulus action to listen to the native close event so we can close everything.
But.... (there's always one), how do you handle the following:
Let's say the user clicks a link, modal with turbo frame opens but the loading time is longer then expected. During this process the user presses the Escape key, the modal closes BUT (there it is) the fetch call is still running, when it's finished it still replaces the turbo-frame and through the MutationObserver the modal gets re-opened.
I tried watching if the turbo-frame has a aria-busy when the close method is being called, but it always is undefined. So my guess these two events are triggered passed each other.
The ultimate solution would be to maybe abort the turbo fetch request all together, or have a way to block the modal from opening again.
Maybe I missed something in the other tutorials and there is a solutions somewhere.
Keep up the nice work!
Sometimes you spend a good amount of time typing a message and find a solution a few minutes after it, I stumbled upon this tutorial, which has the answer for now:
https://symfonycasts.com/screencast/turbo/prevent-frame-rendering
Putting the code below in the controller now prevents the frame rendering from taking place if the modal isn't open (anymore).
If there is more to it, maybe you can let us now.
Hey @webstack
Ha! Yea, sometimes you just need to put your problem into words. Thank you for sharing your solution, and by the way, you can use our search form at the top of the page to look for course-related topics (choose the "In this course" option)
Cheers!
Ah Thanks! Have a good one.
This might just be my favourite episode so far. So many things coming together!
Woo! It might be mine too :)
Hey Hauke,
Thank you for your feedback! We're super happy you liked it :)
Cheers!
"Houston: no signs of life"
Start the conversation!