rickyryden's avatar

How to use Dropzone.js when creating a NEW post in Laravel?

I watched the "Bulk File Uploads" in "Build ProjectFlyer With Me" series and I like how easy Dropzone.js is.

In the video Jeffrey uses DZ to add photos to an existing flyer. My problem is that I would like to use DZ when creating a new post (almost like a blog)...

But when I am at (for example) "post.create" I don't have any post ID or anything to use because the post doesnt exist yet.

Do you guys have any ideas how I can solve this?

One idea I have is to create the post when clicking "create post", but dont publish the post. So instead of post.create, the route will be post.edit (but the user doesn't know that). But that doesnt feel right... And if a user closes the page there will be unpublished posts etc...

0 likes
14 replies
bobbybouwmann's avatar

So there are two ways to solve this. When the user arrives on the create page you already create a post. So you can add stuff to it. Then you can add for example a column in your database called published and you set that default to 0. When the user clicks on the create button you simply update the post with the correct field and you set the published field to 1. You can then query all published articles. You can also then once in a while or with a job delete all the unpublished posts.

The second option would be uploading the images and assigning them later on. So you save the images in the database and when the user saves the post you add the images to that post. This is much more difficult solution, because you need to keep track of the images and to which post they belong.

Sulieman's avatar

@rickyryden an easy way that i use

when you create the article , it will saved in database, but you don't know the ID for the article until you save it So : after you insert the article and upload the images , search for the images where images.created_at == article.created_at and then assigning them

Snapey's avatar

Another approach;

when you supply the edit form, create a random number and place this in a hidden form field.

When the images are uploaded pass through the random number and save it in a new 'key' column on the images table.

When the main form is saved, you will get back the random number from the hidden field. After saving the main form, query the images table and get all the images that have that random key. Then call a save many on the main object and attach all the image ids that you found when searching for the random number.

bobbybouwmann's avatar

@Sulieman I don't think that works correctly.. What happens when two users create a post at the same time? Both post will then have images they didn't uploaded..

1 like
lancebutler2's avatar

Personally, I'd use the second method @bobbybouwmann suggested.

Dropzone has a this.on("success", function(file, response){}) method that you can tap into. Have your endpoint's controller method create the image and return the id within its response's payload. Then use the above dropzone function to update a hidden input field within the form.

Use the value of the hidden input field on submit to add the associated image to the new post via Eloquent's relationship's associate method.

jekinney's avatar

@lancebutler2

What happens when a user refreshes the page? You then won't have access to the data drop zone supplied.

Drop zone by default triggers the upload right away separate from anything else. So as was mentioned you either need to create a post with all null fields when the url is hit or stop the upload by setting drop zone to do that in the options you set and upload when the post article button is hit.

http://stackoverflow.com/questions/18466208/dropzone-js-stop-from-uploading

lancebutler2's avatar

@jekinney

The process would be repeated. A refresh of the page would require a new photo to be uploaded. Visual cues would certainly give that away. Now you likely have an image that has been uploaded (before that page refresh), but is not attached to any post. That's okay, there are things you can do to clear trash (unused) images if you'd like.

Creating a post at page load has the exact same effect. A new pos would sit in the database. I can refresh this page 20 times and have 20 new posts created...sitting in the database, taking up space, having no future of ever being "published"

I feel like it's a pick your poison kinda of question: when you want to use AJAX to upload a "featured image" to a post that has not yet been created...

Do you want the possibility of unclaimed images....or unused posts. Either way works. I'd just personally take the WordPress route...Upload images to a media library (or whatever). If they don't get claimed by a post because of a page reload, no worries. It can sit in a media library NOT being used a feature image.

1 like
rickyryden's avatar

Thank you for all your answers! I think I will do like this, what do you guys think?

1: user clicks create post 2: check if there is an unpublished post (if user closed the window last time etc) 3: if we have an unpublished post from that user -> delete that post + images 4: create a new post and redirect to that post

So the user clicks create post and every time they see a new post. That way I wont get tons of images and unpublished posts... If the user start writing something and then closes the windows... well that's the users problem in this case ;) Maybe in the future I can make it autosave (like Wordpress) but that's not needed right now.

I'm building a "project blog/diary" so the users will post short text updates (with one or more images sometimes).

rickyryden's avatar

1: I like how the dropzone script looks. The user can easily see if the images have been uploaded etc. I think some users are going to upload big images, and if they click submit they might not wait long enough and then close page/refresh/etc. 2: I'm going to add an "add more images to this post" button later on and then I can just use DZ again and I dont have to worry about having both ajax upload and regular upload (even if i can re-use some stuff).

Am I overthinking this or does that make any sense to you why I want the DZ/ajax to work? :D

jekinney's avatar

@rickyryden

They shouldn't take to long to upload. You can limit the size in MB which will help. You can upload the file as is and fire an event to resize them if needed.

@lancebutler2 valid point....

Sulieman's avatar

@bobbybouwmann there is no problem , he have to search for images where image.created_at == post.created_at and image.user_id == post.user_id

i think this is the simplest way

scottzirkel's avatar

Here's what I did to make it work. Not sure if it'll work for every case, but it does what I need it to.

The user can upload images and fill out the form fields in any order. When they drop the images into dropzone, they aren't uploaded right away, they are just queued up. When they hit submit, the Vue component creates the post and sets the Post-Id as a header variable, which gets sent with the image file. That way I have the id & the file data all arriving to the same place at the same time.

The dropzone area does not have to be in the form element for this to work.

Just make sure to return the post from your PostController store method (or whatever you are using to save the Post).

Here's a mockup of the component:

var Dropzone = require('dropzone');
Vue.component('createPost', {
    data() {
        return {
            form: {},
            dropzone: '',
        }
    },
    ready() {
        this.initDropzone();
    },
    methods: {
        initDropzone() {
            Dropzone.autoDiscover = false;
            this.dz = new Dropzone("#addPost", {
                url: '/post',
                autoProcessQueue: false,
            });
        },
        create() {
            var self = this;
            this.$http.post('/post', this.form)
                .then(response => {
                    this.dz.options.headers = {'Post-Id': response.body.post_id};
                    this.dz.processQueue();
                });            
        }
    }
});
jannndo's avatar

Or you could just force the form to be processed with js .submit() method before the dropzone processQueue is triggered. In this way, you are able to fetch the articles ID by fetching the latest article the user posted and add it to uploaded images.

Please or to participate in this conversation.