jaystabins's avatar

A little help with ajax request and overlay while processing

I have an image upload form working really well, I am just looking for some feedback on how to show an overlay while the ajax request is being processed.

I am in pretty deep and just looking for some ideas when it comes to uploading images.

Everything is getting handled in routes, it will not end this way but just in this test project it is here, so here is the route....


Route::post('image', function(Illuminate\Http\Request $request) {

$file = $request->file;

$mime =         $request->file->getClientMimeType();
$size =         $request->file->getClientSize();
$extension =    $request->file->getClientOriginalExtension();

$image_name = time() . '-' . $request->title . '.' . $extension;
$thumb_name = time() . '-' . $request->title . '-thumb.' . $extension;

$local_path = '/uploads/' . date('Y') . '/' . date('m') . '/';
$directory = public_path() . $local_path;
$thumbs_path = $directory . '/thumbs/';

if(!file_exists($directory))
{
    File::makeDirectory($directory, 0777, true);
}
if(!file_exists($thumbs_path))
{
    File::makeDirectory($thumbs_path, 0777, true);
}

$file->move($directory, $image_name);

$image = Image::make(sprintf( $directory . '/%s', $image_name));
$image->resize(600, null, function ($constraint) {
            $constraint->aspectRatio();
            $constraint->upsize();
        });
$image->resize(null, 600, function ($constraint) {
            $constraint->aspectRatio();
            $constraint->upsize();
        });
$image->save();

File::copy($directory . $image_name, $thumbs_path . $thumb_name);
$thumb = Image::make(sprintf( $thumbs_path . '/%s', $thumb_name));

$thumb->fit(200, 200, function ($constraint){
    $constraint->upsize();
});

$thumb->save();

$img = [
    'url' => asset($local_path) . '/' . $image_name,
    'thumb_url' => asset($local_path . 'thumbs/' . $thumb_name),
    'file_name' => $image_name,
    'file_size' => $size,
    'title' => $request->title,
    'caption' => $request->caption,
    'alt_text' => $request->alt_text,
    'description' => $request->description,
    'mime_type' => $mime,
    'user_id' => 1
];

$new = App\Image::create($img);

if($request->ajax())
{
    $response = '<img class="grid-item" src="' . $new->thumb_url .'" alt="'. $new->alt_text . '" id="' . $new->id . '" target_url="' . $new->url . '"/>';
    return $response;
}

return redirect('image');

});

calling this by this ajax request


        $( '#submit-new-image' ).on( 'submit', function(e){
             e.preventDefault();
         var formData = new FormData(document.getElementById("submit-new-image"));
         
         $.ajax({
            type: "POST",
            url: "{{ url('image') }}",
            xhr: function() {  // custom xhr
                myXhr = $.ajaxSettings.xhr();
                if(myXhr.upload){ // if upload property exists
                    myXhr.upload.addEventListener(); // progressbar
                }
                return myXhr;
            },
            success: function(item){
                addGridItem(item);
                $('#submit-new-image').trigger("reset");
                $( '#placeholder' ).addClass( "hidden" );
            },
            error: function(jqXHR, textStatus, errorThrown){
                console.log("Problem uploading file!");
            },
            data: formData,
            cache: false,
            contentType: false,
            processData: false
         });
    });

everything works as expected, I can add photos, everything gets persisted without error, but while uploading a large file this can take up to 10-15 seconds.

Looking for some ideas about how to display that things are working for the user.......

0 likes
2 replies
bimalshah72's avatar

@jaystabins

You can create your partials view - say loading.blade.php having content only .. with import font awesome - with display none

<i id-"loading" style="display:none" class="ace-icon fa fa-spinner fa-spin {{ $color or 'grey' }} bigger-{{ $size or '250' }}"></i>

you can also use any other animated waiting symbol

normally you need to put this in the area where you are going to call ajax call for example

<div class="padding-4 text-center" >
        <br><br>
        @include('loading')
    </div>

now here is the trick..check my comment line //*******************************************

  $( '#submit-new-image' ).on( 'submit', function(e){
         e.preventDefault();
         var formData = new FormData(document.getElementById("submit-new-image"));
         $('#loading').show(); //****************************************/ showing loading symbol
         $.ajax({
            type: "POST",
            url: "",
            xhr: function() {  // custom xhr
                myXhr = $.ajaxSettings.xhr();
                if(myXhr.upload){ // if upload property exists
                    myXhr.upload.addEventListener(); // progressbar
                }
        
                return myXhr;
            },
            success: function(item){
                addGridItem(item);
                $('#submit-new-image').trigger("reset");
                $( '#placeholder' ).addClass( "hidden" );
         $('#loading').hide(); //*******************************************
            },
            error: function(jqXHR, textStatus, errorThrown){
                console.log("Problem uploading file!");
         $('#loading').hide(); //*******************************************
            },
            data: formData,
            cache: false,
            contentType: false,
            processData: false
         });
    });

Please or to participate in this conversation.