Chapters
40 Chapters
|
4:39:58
|
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!
25.
Dropzone: AJAX Upload
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 is built on Symfony 4 but works great in Symfony 5!
What PHP libraries does this tutorial use?
// composer.json
{
"require": {
"php": "^7.1.3",
"ext-iconv": "*",
"aws/aws-sdk-php": "^3.87", // 3.87.10
"composer/package-versions-deprecated": "^1.11", // 1.11.99
"doctrine/annotations": "^1.0", // 1.10.1
"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.1
"knplabs/knp-paginator-bundle": "^2.7", // v2.8.0
"knplabs/knp-time-bundle": "^1.8", // 1.9.0
"league/flysystem-aws-s3-v3": "^1.0", // 1.0.22
"league/flysystem-cached-adapter": "^1.0", // 1.0.9
"liip/imagine-bundle": "^2.1", // 2.1.0
"nexylan/slack-bundle": "^2.0,<2.2.0", // v2.1.0
"oneup/flysystem-bundle": "^3.0", // 3.0.3
"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.4
"stof/doctrine-extensions-bundle": "^1.3", // v1.3.0
"symfony/asset": "^4.0", // v4.2.3
"symfony/console": "^4.0", // v4.2.3
"symfony/flex": "^1.9", // v1.21.6
"symfony/form": "^4.0", // v4.2.3
"symfony/framework-bundle": "^4.0", // v4.2.3
"symfony/property-access": "4.2.*", // v4.2.3
"symfony/property-info": "4.2.*", // v4.2.3
"symfony/security-bundle": "^4.0", // v4.2.3
"symfony/serializer": "4.2.*", // v4.2.3
"symfony/twig-bundle": "^4.0", // v4.2.3
"symfony/validator": "^4.0", // v4.2.3
"symfony/web-server-bundle": "^4.0", // v4.2.3
"symfony/yaml": "^4.0", // v4.2.3
"twig/extensions": "^1.5" // v1.5.4
},
"require-dev": {
"doctrine/doctrine-fixtures-bundle": "^3.0", // 3.1.0
"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.2.3
"symfony/dotenv": "^4.0", // v4.2.3
"symfony/maker-bundle": "^1.0", // v1.11.3
"symfony/monolog-bundle": "^3.0", // v3.3.1
"symfony/phpunit-bridge": "^3.3|^4.0", // v4.2.3
"symfony/stopwatch": "4.2.*", // v4.2.3
"symfony/var-dumper": "^3.3|^4.0", // v4.2.3
"symfony/web-profiler-bundle": "4.2.*" // v4.2.3
}
}
18 Comments
HAY IT'S 2023! and here I am saying thank you with my best scooby-doo dog voice
RHANK RHOU! RAGGY!
Don't mind me, just delirious.
Chasing a deadline.
This helped.
Hahaha, thank you @Aries!
Hello Ryan and thanks for the tutorial, i have followed it and with some minor tweaks i created A gellery of images that can be reordered!
I'm trying to recreate some parts for another part of my app but I'm having the problem when i start an ajax request it redirects me and shows me the json in the screen.
My controller
/**
* @Route("/admin/addPage", name="add_page", methods={"POST"} )
*/
public function addPage(Request $request)
{
$page = new Page;
$slug = $request->get('page_slug');
$page->setSlug($slug);
$this->em->persist($page);
$this->em->flush();
return $this->json(
$page,
201,
[],
[
'groups' => ['main']
]
);
}
my form
<form action="{{ path('add_page') }}" method="POST" class="js-add-page">
<div class="form-group">
<label>{{ 'page_manager.slug'|trans }}</label>
<input type="text" class="form-control" name="page_slug">
</div>
<button class="btn btn-primary ">{{ 'page_manager.create_page'|trans }}</button>
</form>
Thanks!
Hey Ernest R.
I guess everything is looking good here but what about JS? Have you stopped original browser event? You button just submits form that's why you are redirected. You should stop the original submit event with
event.preventDefault()depending on how you are doing ajax request!Cheers!
Hi Vladimir,
I finnaly discard using ajax for create the register, was not worth it for just one field i have to enter.
I tried using the event.preventDefault(), and could stop the submit, but i wasn't able to used inside the class as is used in the example, so i used in the document.ready, but after that i couldn't execut the ajax call, no error, no warning, i guess i wasn't pointing correctly to the mark.
My js script ( added a id to the form)
`
$(document).ready(function() {
document.getElementById("js-add-page").addEventListener("click", function(event){
});
});
class PageList
{
}
`
Thanks Vladimir.
hm...
$('.js-add-page')is a form element, so you should listen tosubmitevent instead ofclicksomething like thischeers!
Sorry, but what about the real multiple files uploading?The Dropzone.js uploads the files one by one. Can you please advice how to count then the uploaded files (at once) on the server side? Thank you
Hey Anton,
This comment might be useful for you, please, take a look at it: https://symfonycasts.com/sc... . But really, having nice JS library that helps to handle multiple uploads is enough. Fairly speaking, upload files one by one technically has less possible problems, and if you have a nice JS library with nice UI and UX - that's perfect. You should not care about how it works behind the scene - all the job is done by JS library. What you do care is UX and that handling single file uploads on the server side is just easier. So, as for me, the ideal scheme for uploading multiple files - have a JS library with nice UX that allows users to select multiple files at once and that uploads those files one by one to the server side where your PHP script handles those uploads.
I hope this helps!
Cheers!
Hi! How do you solve the new item issue? What I mean is, I create a new Article, in the form I fill all the fields and upload some files.. we don't know the new article_id, how do you store them? How do you do the relationship? Thanks
Hey Roberto S. !
Great question :). I cheat.. and I feel great about it :). If I have an upload on some sort of an entity, I *always* will save the original object (e.g. Article) first. It just makes life MUCH simpler. There are bundles out there that have really cool fanciness to save files in a temporary location that you can then read when your form actually submits... but I've never thought it worth the trouble. For an Article, it would look like this:
Add a step 1 where the user at least needs to set a "title" so you have *something* to add to the database. You'll then need to put any "NotBlank" annotations you want in some validation group that will only be activated on the 2nd step. Btw, for that "step 1". I've even seen it where it looks like 1 form, but first you only see the title. Once you type that in, it saves via AJAX and the rest of the form loads.
In the end, the problem you're referring to simply is a tricky one. That's why I like to cheat. There are bundles that can help (I think https://github.com/1up-lab/... has this), but it ultimately comes down to some tricks. For example, you could also allow your related objects to save with a null article_id... store THEIR ids in the session (or, more fancy, return their ids back, and put them in the form as hidden fields) and set them when the form FINALLY saves (and have a process to clean up old records for forms that NEVER got submitted successfully).
Let me know if this helps :).
Cheers!
Hey guys,
Is it possible for dropzone to send the form data as json?
Hey Skylar!
Hmm, maybe? :) There are two parts to that:
1) First, you'll need to base64 encode the uploaded file data so that it can be sent. That *does* appear to be possible: https://stackoverflow.com/q...
2) Then you need to teach Dropzone to send JSON, instead of the normal format. I'm not sure that's possible. Someone forked the entire library to add it - https://github.com/slothbag... but they changed a lot of core code to make it possible. Someone else "sorta" did it - https://github.com/rowanwin... - but that's a bit of a hack: they are *still* sending a traditional form submit, but with JSON as one of the keys (it's not *really* a JSON formatted request).
So... it looks like... kind of :). If you want an "pure" JSON upload endpoint for some other use (beyond Dropzone), the easier solution might be to have your endpoint support both JSON input and normal, form-submitted input (from Dropzone).
Cheers!
And why, just why we don't use Symfony forms????????
Hey sasa1007!
Haha, we could! But this form would just have one field... and that field would be an instance of an UploadedFile object. So, I'm not sure the form would give us much in this case. But, what do you think?
Cheers!
Hi!!!!
I'm glad that You understand my comment in the right way :-), I enjoy watching this tutorial.
So my idea is to create one entity - Medias, and only in Medias to upload files. Medias will be related to every entity that we need picture (Blog entity, User entity....). From user perspective, user can upload more picture at once in Medias (somehow), and then he can use those pictures (one or more) for blogs or blog or other entity where picture is needed. And at the end I want to copy that entity, and logic for upload from project to project and reuse that, and of course I want to use symfony components(forms). And now when I use symfony forms dropzone trow error that he can find url.
Hey sasa1007!
Makes sense! Honestly, what you probably want is a setup like what we have here - where you use Dropzone outside of a a form to create the Medias and relate it to whatever object you need (you would need to send up some additional flag in the URL to say which object the Media should be related to). But, there are so many variants on how you can want this to look and work.
So, are you creating a traditional Symfony form then adding a Dropzone inside of it? By default, Dropzone will use the
action=""of your form tag as the upload URL. You can by passing aurloption when you initialize Dropzone. But then, Dropzone isn't really using your form... it's still uploading independently of your form.That's a long way of saying: what exactly are you trying to accomplish by putting it into a form? What is the user flow you imagine?
Cheers!
Thanks!!! :D
Cheers!!
"Houston: no signs of life"
Start the conversation!