keithmclaughlin's avatar

Store filenames/URLs of images uploaded before form is submitted.

Hi folks,

What would be the best way to store/associate filenames or URLs with form data when adding a new record to a database?

As a basic example:

If I had a form for adding a new blog post with fields for title, content and images, where the images were uploaded using the likes of FilePond or Dropzone.js (drag and drop).

As each file gets uploaded (to S3 for example) how would one save/store the filename or URL so that when the forms is submitted that the new record also has references to all the images that were uploaded before the form was submitted?

Would you save the info in a hidden field on the form? Or in json? Or another way?

I appreciate your help.

0 likes
7 replies
jlrdw's avatar

Look at this simple example: https://gist.github.com/jimgwhit/0e4929230cd6b7df4b274b0b04312edd

Notice the line where the uploaded file gets a name:

$newname=$filename.$lid.".".$file_ext;  // use however you name

But to get the name to store see this line:

$dogpic=$newname;

I could have just used $newname, but like sticking to field names:

So in the above, and this is just an example:

A file named rover473.jpg gets uploaded.

The text rover473.jpg gets stored in the dogpic field.

To display later in view:

<img src="{{ asset('assets/upload/imgdogs') . '/' . $row->dogpic }}" alt="" class="image">

Of course if storing images in a child table, see inserting and updating related data in the docs.

https://laravel.com/docs/7.x/eloquent-relationships#inserting-and-updating-related-models

martinbean's avatar

@keithmclaughlin If you upload the files to S3 asynchronously, then you could just add the filenames (or model IDs if you create some form of image/attachment model on upload) to the form so that when the form is submitted, those files are then associated with your post model.

If people are able to upload multiple files asynchronously I’d also put some form of “clean-up” in place. You could first upload files to a “temporary” directory or an entirely different bucket in S3. When the post form is submitted, move the named files to your “main” directory/bucket. You can then add a lifecycle rule to delete any objects from the temporary directory/bucket that are older than say, 24 hours. This would be so you’re not holding on to “orphaned” files that have been uploaded but then not associated with a post.

keithmclaughlin's avatar

@jlrdw Thanks for replying but I already understand how to get the filename from the upload. Maybe my question wasn't explained clearly enough.

When adding a new blog post (PostsController & Post Model), the form will have a drag & drop field to upload multiple images (UploadController / ImageController). Every image uploaded (via ajax) will return a filename, but where can I store that filename in the new blog post form, so that when the PostsController handles the new blog post it knows which filenames were uploaded?

Does that make more sense?

keithmclaughlin's avatar

@martinbean In your reply "then you could just add the filenames (...) to the form so that when the form is submitted, those files are then associated with your post model.". Exactly... but how? A hidden field on the new blog post form? Some sort of javascript object?

Thanks for replying.

martinbean's avatar
Level 80

@keithmclaughlin You’d inject the hidden inputs to your form as a file is uploaded:

// in some event listener…
var input = document.createElement('input');
input.type = 'hidden';
input.name = 'file[]';
input.value = filename_of_uploaded_file;
form.appendChild(input);

These will then get sent when your form is submitted.

Look at the documentation for whatever file uploading library you’re using as they will almost certainly offer a callback for when a file is successfully uploaded.

Please or to participate in this conversation.