I'm using a form in Laravel 5.1 to post some text and to upload a file. It looks like this (simplified version):
{!! Form::open(array('url' => 'foo/bar')) !!}
{!! Form::text('image_name') !!}
{!! Form::file('image') !!}
{!! Form::submit('Submit!') !!}
{!! Form::close() !!}
The textfield is required, so I added a $validator
in my controller. If validation fails, the user is redirected back to the form. I use the withInput()
method to repopulate the form so that the user doesn't have to fill it in again:
if ($validator->fails()) {
return redirect()->back()->withInput();
}
This will get the old input back for textfields, dropdowns etc. But if the user has uploaded a file, the file selection is gone when validation fails and has to be selected again. Is there any way in Laravel to remember file selection as old input?
Thanks!
No, the
file
input can't be prepopulated by Laravel or by any software. Your website (and any website) doesn't and shouldn't know the local path to the file. Imagine the security risks if they did! You could trick a user into uploading their SSH private key or something.What you need to do is process the uploaded file regardless, even if there are validation errors.
Then you could either store it in your database with a
pending
status, or have some uniquehash
assigned to it, with a matchinghash
stored in the user's session. The point is to be able to identify incomplete uploads that belong to this specific user.Then when you display the form, retrieve those incomplete files either from the session or database, and display the thumbnail next to the file upload. This tells the user that they don't need to re-upload that file. Just make sure that they have a way to remove it as well in case they changed their mind.
Once the form is submitted correctly then clear the session
hash
or update the database status tocomplete
; whatever you need to do.There seems to be a lot of questions around for the same issue (Form::file: How to repopulate with Input::old After Validation Errors and/or on Update?) and everyone with apparent knowledge says that is not possible.
I would proppose a workaround that covers the following goals:
don't needSHOULD NEVER USE javascript validation.The keyword of it all is AJAX. I would do the following:
December 2017 update: Send all fields and attached files by a single AJAX POST
GETPOST) that contains everythingexceptincluding file input. Remember that it requires to send the Laravel CSRF token.This way you avoid to have files in any temporal state in your server.
A more complex but improved version of this process, if you are worried about used bandwidth and you expect having errors in your input fields will be very common, you may do two (or more) AJAX POST validations: The first one with the input fields only, and if it's ok, send all fields (input fields again, now including the attached files) to attempt validation again and do actions with all data in case of success.