Chapters
46 Chapters
|
4:55:39
|
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!
19.
Making a Configurable, Reusable Controller
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.
This tutorial works perfectly with Stimulus 3!
What PHP libraries does this tutorial use?
// composer.json
{
"require": {
"php": ">=8.2",
"ext-ctype": "*",
"ext-iconv": "*",
"composer/package-versions-deprecated": "1.11.99.1", // 1.11.99.1
"doctrine/annotations": "^1.0", // 1.11.1
"doctrine/doctrine-bundle": "^2.2", // 2.2.3
"doctrine/doctrine-migrations-bundle": "^3.0", // 3.0.2
"doctrine/orm": "^2.8", // 2.8.1
"phpdocumentor/reflection-docblock": "^5.2", // 5.2.2
"sensio/framework-extra-bundle": "^5.6", // v5.6.1
"symfony/asset": "5.2.*", // v5.2.3
"symfony/console": "5.2.*", // v5.2.3
"symfony/dotenv": "5.2.*", // v5.2.3
"symfony/flex": "^1.3.1", // v1.21.6
"symfony/form": "5.2.*", // v5.2.3
"symfony/framework-bundle": "5.2.*", // v5.2.3
"symfony/property-access": "5.2.*", // v5.2.3
"symfony/property-info": "5.2.*", // v5.2.3
"symfony/proxy-manager-bridge": "5.2.*", // v5.2.3
"symfony/security-bundle": "5.2.*", // v5.2.3
"symfony/serializer": "5.2.*", // v5.2.3
"symfony/twig-bundle": "5.2.*", // v5.2.3
"symfony/ux-chartjs": "^1.1", // v1.2.0
"symfony/validator": "5.2.*", // v5.2.3
"symfony/webpack-encore-bundle": "^1.9", // v1.11.1
"symfony/yaml": "5.2.*", // v5.2.3
"twig/extra-bundle": "^2.12|^3.0", // v3.2.1
"twig/intl-extra": "^3.2", // v3.2.1
"twig/twig": "^2.12|^3.0" // v3.2.1
},
"require-dev": {
"doctrine/doctrine-fixtures-bundle": "^3.4", // 3.4.0
"symfony/debug-bundle": "^5.2", // v5.2.3
"symfony/maker-bundle": "^1.27", // v1.30.0
"symfony/monolog-bundle": "^3.0", // v3.6.0
"symfony/stopwatch": "^5.2", // v5.2.3
"symfony/var-dumper": "^5.2", // v5.2.3
"symfony/web-profiler-bundle": "^5.2" // v5.2.3
}
}
What JavaScript libraries does this tutorial use?
// package.json
{
"devDependencies": {
"@babel/preset-react": "^7.0.0", // 7.12.13
"@popperjs/core": "^2.9.1", // 2.9.1
"@symfony/stimulus-bridge": "^2.0.0", // 2.1.0
"@symfony/ux-chartjs": "file:vendor/symfony/ux-chartjs/Resources/assets", // 1.1.0
"@symfony/webpack-encore": "^1.0.0", // 1.0.4
"bootstrap": "^5.0.0-beta2", // 5.0.0-beta2
"core-js": "^3.0.0", // 3.8.3
"jquery": "^3.6.0", // 3.6.0
"react": "^17.0.1", // 17.0.1
"react-dom": "^17.0.1", // 17.0.1
"regenerator-runtime": "^0.13.2", // 0.13.7
"stimulus": "^2.0.0", // 2.0.0
"stimulus-autocomplete": "^2.0.1-phylor-6095f2a9", // 2.0.1-phylor-6095f2a9
"stimulus-use": "^0.24.0-1", // 0.24.0-1
"sweetalert2": "^10.13.0", // 10.14.0
"webpack-bundle-analyzer": "^4.4.0", // 4.4.0
"webpack-notifier": "^1.6.0" // 1.13.0
}
}
16 Comments
Hi Guys,
Great tutorial! There is a part in the video that I did not quite understand, maybe someone can help?
What is the purpose of creating the submitAsync value and how does it help. I did no quite understand the explanation.
Thanks!
Hey Sydney!
Let's try to figure it out together! :) Well, first of all, the
submitAsyncvalue is just a boolean flag, I suppose you understand it well because it's pretty simple. It just says either we want to send this form "async" or "sync", and that's it. And we can control what kind of form sending we want for different controllers. What about actual sending the form async/sync - that's pretty simple too. We either send the form sync with "this.element.submit();", i.e. just literally ask the browser to submit that form as usual and reload the page. Or if we want to send it async - we intercept the normal browser's form sending and instead send an ajax request with all the form data viafetch()that will return us a response that we will handle later. I.e. no normal page refresh by the browser.In short, we either let the browser to send the form as usual with the page refresh... or send an ajax request instead to avoid the page refresh, and that's it. I hope it's clearer now :)
Cheers!
Thanks a lot Victor. Its clear now.
Hi guys
Great tutorial, I liked stimulus.
I'm trying to use modal_form_controller to edit the data as well.
I have to prevent some fields from being overwritten.
I am using "disabled" in _form.html.twig:
Unfortunately, when I approve such a form, I get an ugly exception:
Expected argument of type "string", "null" given at property path "nr".
If I edit without disabled in this field everything works fine ...
I would be grateful for suggestions on how I can fix this.
Hey Artur,
Hm, it sounds like you need to allow your "nr" field to be nullable, most probably in the setter and property declaration. Or, maybe try to use readonly instead, but IIRC it might be hacked in the HTML code by some tricky users.
I hope this helps!
Cheers!
Thanks Victor for the quick hint!
"readonly" works great for me.
Your burglary alert scared me a bit, but at least I can move on with my project.
Regards.
Hey Artur,
Great, I'm happy it works for you! About the alert, you may try to open Chrome inspector and remove that readonly attribute in the HTML code of the loaded page - then you will be allowed to edit the field and if you send the form - server will update the value of that field in theory. You can try do it yourself so that you know how some users may bypass this readonly attribute. If it's a critical thing for you - I'd recommend you to revert back to disabled and try to find the solution with allowing null for that field instead.
Cheers!
Fun story. The way you used
fetch()withbody: new URLSearchParams(new FormData(this.element))doesn't work with all form methods. WithGETyou get an error saying thatGETorHEADcan't have a body.If you want, you can use something like this to make the form submit work with any request method.
`
let url = this.element.action;
let init = {method: this.element.method};
if (['get', 'head'].includes(this.element.method)) {
} else {
}
const response = await fetch(url, init);
`
Thanks for the content Ryan!
Yo Justin!
Ya know, I had never really thought about that, but that makes sense! And I love your solution - just
toString()'ing the UrlSearchParams - very nice. Thanks a bunch for sharing this :).Cheers!
hey, silly question if you don't mind,
what makes "Server" label on your developer toolbar (bottom right ) green?
Hey Jakub G.!
Actually, this caused some of the team internally to say "Hmm, that's a good question - what exactly *does* trigger that?" - so it is a good question ;). I believe it turns green based on one of two things:
A) In practice, it turns green if you're running the symfony binary AND docker-compose. It turns green because the symfony web server noticed docker compose, reads the running containers, and exposes some env vars.
B) OR, it may turn green if ANY of the items in the sub-menu are green. In practice, for me, my green items are because I'm running Docker Compose, so it's kind of the same answer as (A). But there are a few other items that could possibly be green also: https://imgur.com/a/FV9dkxB
So I'm not 100% sure - but that should give you the basic idea :).
Cheers!
Hi there!
First of, great course so far! Yay!
Next, I followed a couple of your JavaScript-related tutorials and I think one piece is missing. What about internationalization? I've been wondering for a while, what would be the best approach to use the same translation strings we used in the PHP side inside the JS. For example, the default 'Yes' from that lesson or even the cancel button from Sweetalert. So far I've been using some data to dump text in the dom that JS can read, I've been making some JSON endpoint that JS can query. But I was wondering, what would be the recommended way of doing that.
I live in Québec and almost every app I make has to be French and English...
Cheers!
Hey Julien,
Unfortunately, no any screencasts about translations so far, but we're going to create a tutorial about it in the future, it's on our TODO list. But I can't say when i might be released yet. But I can give you some hints :) Take a look at this bundle: https://github.com/willdura... - it helps to dump some translations to the frontend and use similar to how you use them in PHP files. But basically, your way sounds like a good workaround too, but the bundle is just helps to "standardize" it and has some more useful tools.
I hope this helps!
Cheers!
If I pass
submitAsync: false,(rather than true), it still submits asynchronously. And if Iconsole.log(this.submitAsyncValue);in the submitForm() method it does show 'true' even though 'false' was passed. What's going on there?And I do have submitAsync registered in the values object as bool:
submitAsync: Boolean,Hey John christensen!
I need to check into this - but I think this might be a bug on my part. Or, probably more accurate, a bug in WebpackEncoreBundle's Stimulus controller. I noticed this just a few days ago: if you pass submitAsync: false, it STILL renders the attribute, just without any "=" part. But that's enough for Stimulus to see the presence of this attribute, and think that you want to set it to true.
Cheers!
Here's the issue tracking this - https://github.com/symfony/... - I'm going to have someone check into it and (assuming there IS a bug, which I think there is) fix it soon :).
Thanks for bringing this to my attention!
"Houston: no signs of life"
Start the conversation!