0

I am working on a Laravel project and I have routes set up for a form page where it shows the form on GET and it analyzes it on POST:

Route::get('/update-data', [
    'as'   => 'user.settings.edit-data',
    'uses' => 'UserController@editData',
]);
Route::post('/update-data', [
    'as'   => 'user.settings.update-data',
    'uses' => 'UserController@updateData',
]);

In this form I ask the user to fill out two fields with text and I also ask them to upload two files. Both files must be jpeg, png or pdf. In the controller I have:

$this->validate($request,
    [
        'phone' => 'required',
        'email' => 'required|email',
        'file1' => 'required|mimes:jpeg,png,pdf',
        'file2' => 'required|mimes:jpeg,png,pdf',
    ]);

If that succeeds, then the code will continue executing and save everything, but if not it will redirect the user back to the form. Is there a way to still have the file chosen so that the user doesn't need to look for it again?

Zachary Weixelbaum
  • 904
  • 1
  • 11
  • 24
  • Maybe you could save the file that is validating fine to a temporary place, show the user a thumbnail instead of the file input and only show a file input for the invalid file. – solarc Feb 14 '17 at 16:47
  • I could do that or I can use Javascript to not even submit unless it is valid. I just want to know if there is a built in way to do it – Zachary Weixelbaum Feb 14 '17 at 16:53

1 Answers1

0

I would suggest validating using server side code (not javascript, although both can be nice from the user perspective (but obviously don't rely on the js validation).

I usually validate like this in Laravel (I'm not the biggest fan of their built in validator). Then after the validation you can use Laravel's File class to get the file name and re-post the data to the view:

$file     = Request::file('file1');
$accepts  = ['jpeg', 'png', 'pdf']; 
$ext      = $file->getClientOriginalExtension();
$filename = $file->getClientOriginalName();

if( !in_array($ext, $accepts) )
{
  return view('your-view')->withErrors('Invalid File Format');
}
else
{
  //File has one of the correct extensions, 
  //return the filename to the view so it can be
  //re-displayed in the input
  return view('your-view', ['filename' => $filename]);
}

Or if you prefer the non-facade way:

$file     = $request->file('file1');
$accepts  = ['jpeg', 'png', 'pdf']; 
$ext      = $file->getClientOriginalExtension();
$filename = $file->getClientOriginalName();

if( !in_array($ext, $accepts) )
{
  return view('your-view')->withErrors('Invalid File Format');
}
else
{
  //File has one of the correct extensions, 
  //return the filename to the view so it can be
  //re-displayed in the input
  return view('your-view', ['filename' => $filename]);
}

This takes advantage of Laravels File class.

Chad Fisher
  • 353
  • 4
  • 16
  • That might be able to return the name of the file, but the browser won't know where the file is located in the structure of my computer's file system – Zachary Weixelbaum Feb 15 '17 at 14:57
  • For security reasons you can't to the best of my knowledge. I would take a closer look at this: [Keeping Input](http://stackoverflow.com/questions/967916/how-to-keep-input-type-file-field-value-after-failed-validation-in-asp-net-mvc). If you are truly trying to preserve the file after an invalid input submission you most likely have to save it as a temp on your server. – Chad Fisher Feb 15 '17 at 15:33
  • Sadly, that's the general consensus. Instead, you can also add Javascript validation to prevent the form from ever sending until it is valid – Zachary Weixelbaum Feb 15 '17 at 15:47
  • I agree :D! Gl brother. – Chad Fisher Feb 15 '17 at 15:56