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',
],
];
19 Comments
Hi ,
Thanks for video.
I don't see any error and I don't see any affects (4:50) - page loading styles.
Just in case I copied homepage.html.twig from your script.
Turbo - works , I don't see any errors in browser console.
How to investigate issue?
BR.
Hey @Ruslan
That's a complex question, these effects depend on the browser, and probably some of them will not work at all. Probably if you share what browser you are using, I will be able to help more.
Cheers.
What is the status on the morphing functionality? I have the latest turbo version but adding the meta tags in the head as per the documentation doesn't seem to do anything
Hey @Nick-F!
Morphing is alive and well on Turbo 8, though I admit that I don't have any real experience with it yet (not because it's bad or anything, I've just not been available!). If you have the
metatags, I can't think of a reason why you wouldn't see the morphing functionality... which I realize isn't much help, but maybe it'll give you more confidence to try again.Cheers and good luck!
Hello.. When I add
data-turbo-frame="voyage-list"to the <form> element (~3:22 in the video), I don't see any change when searching. It still does a full-page reload and the cursor resets to the beginning of the <input> field. I have triple checked everything, but don't know where to look. Any ideas?Hey @CDesign!
Sorry for my VERY slow reply! I would check a few things:
A) Is Turbo running otherwise - like do you see no page reloads during normal navigation? My guess is yes, but we need to check.
B) Watch your browser console closely. Do you see any errors? It's possible that the form is submitting into the frame... but then some error (e.g. a 500 error) is causing the response to NOT contain the matching frame... and then perhaps (I can't remember if it actually does this), the entire page is refreshing.
If you're still having the issue and this doesn't help, let me know!
Cheers!
Hey !
Thanks for the work !
A little suggestion : During this video you said that the table doesn't contain links. However, we have the planet links in the turbo-frame
planet-card-{id}.I don't know it's possible, but it could be cool to know : How can I force a page reload on a link who's come from another turbo-frame in the actual turbo-frame ?
PS : I don't remember, it can be myself who's added the planet link :D.
Hey Adn,
Hm, maybe you add it yourself :p Anyway, if you want to reload content in the specific frame - I believe you need something like this:
I.e.
data-turbo-action="replace"should do the trick, you just need to point that link to specific frame, and specific URL of course. It might be so that it will work with empty href though, i.e. it will be pointed to the same URL you're currently on, but I didn't try it :)I hope this helps!
Cheers!
Thanks for your reply !
My bad, a
target="_top"is enough...It still new for me ! Sorry for the inconvenience ! :D
just for clarification for others
in file _card.html.twig
Hey Adn,
Ah, ok, no problem :) Yeah, it's easy to stuck in new stack ;) thanks for sharing your final solution with others!
Cheers!
Hello!
I noticed when the sleep was removed, we see the quick flash when updating the table. Is there a way to say "only add aria-busy after waiting 300ms"?
Hey @kbond!
After talking with you on Slack, you basically figured this out on your own... then told ME. Yes! It's awesome! We can delay the CSS transition so it only happens if the page load is particularly slow. All in CSS:
I LIKE that
Thanks for this great tutorial!
Adding data-turbo-action="advance" makes the page jump back to the top of the page again when searching, clicking on the sorting or paging links. Removing it fixes that again. I thought I missed something, but copied your exact code and it still does it. Has something changed since?
Also, the planet popovers do have a link... which now have "content missing". they should have a data-turbo-frame="_top" I guess?
Using stimulus '3.2.2 and turbo 7.3.0
Update: the issue with the page jumping to top after using data-turbo-action="advance" happens in Brave browser, not on Firefox, Chrome or Edge.
Hey @escobarcampos!
Ah, fascinating! It works in every other browser? I would not have expected that detail to be browser-dependent...
Hello! I have a few questions about this "homemade datatable" :)
Requests are submitted via Ajax using Turbo Drive (if I understood correctly). But if our application is not ready to accommodate Turbo Drive (since all our Javascript must use Stimulus), what should we do?
This question follows on from the 1st. Do you think it is possible to shift all this logic into a LiveComponent? As well as the method that will return the results? I mean, can we in LiveComponent create a LiveAction that we can set the #[MapQueryParameter] to in order to make this all work?
This question follows on from the second. If it is possible to put all the logic in LiveComponent, if we don't use Turbo Drive (but we can use Turbo Frame since it doesn't require Turbo Drive, if I understood correctly. Or maybe there is be alternatives to make all of this work the same way without ever using Turbo), do you think it is possible to create a trait (like ComponentWithFormTrait but something like "ComponentWithDataTableTrait"), and this trait would define all the logic and we would have some abstract methods to define such as the targeted entity, the repository method to use, the sort columns, etc.. And everything would be done automatically?
Hey @Fabrice!
Sorry for the slow reply! But I'm happy to chat about this topic!
For this example of data tables, the Ajax is submitted via Turbo Frames - we put a frame around the
<table>. So, this only means that any JavaScript behavior inside the frame needs to be written in Stimulus. The rest of your site should be ok without it. So, you would disable Turbo Drive (like we talk about in the Drive chapter), but then use frames for this. It is possible that using theadvancemight not play nicely with a disabled Turbo drive... I'm not sure. It's worth a try!Yup! You'll need this PR - https://github.com/symfony/ux/pull/1230 - in order for the URL on the page to change, but I'll merge that really soon. And you might not even need a
LiveActionI would bind the search input to aLivePropmodel, then the navigation links would trigger a model change for apagemodel - e.g. changing it from 2 to 3.Yea! Definitely! That's a really cool idea. More broadly, I'd love to see a PHP library we could use to help build the "data table" and the sort column links, etc. But, anyway, if you built this all inside of a LiveComponent, indeed, I think there would be a lot of boilerplate code. You could have the
queryas aLiveProp(writable:true), a$page = 1as aLiveProp(writable: true)and also 2 for sort direction and sort column. You could have one abstract method - e.g.getQueryBuilder()- where you would use the$queryprop to create the query builder for that entity. Then a method - e.g.getResults()in your trait - that calls this method, sets the orderBy on it, initializes the pagination and returns it. You would usethis.resultsin your template to loop over. Finally, you might have some sort of helpers to help build the pagination links and column sorting headers.If you try this out, I'd love to know how it goes. It feels generic enough that it could at least be something shared publicly.
Cheers!
Thank you for your reply ! So I will try all this soon when I have time, and post the result to you!
thank you !
"Houston: no signs of life"
Start the conversation!