0

I want to be able to upload image with AJAX capability asyncronously. I have visited a lot of websites about uploading image with AJAX and I have tried a lot of combination of codes, but although the people who shared the solution said that it was running properly, I think all of them is rubbish. Because, I couldn't upload any image with AJAX without submit event. I want to emphasize this point that I can already upload the image with button which is type of form submitting like in here: AJAX Uploading in StackOverflow But I don't want it. I just want to use uploading image process without submitting the form so that I can use this image inside my blog editor interface before submitting the article. I believe that this is possible, because this is AJAX and we are in 2015. But I need an answer saying this is possible and I need a solution or a way which is going to the solution. Here is the code which I extracted from my blog site and I would like to express it is the code that is the closest solution. Because, in this stackoverflow question, there is a powerful rate which indicate that this is useful:(By the way, I don't want uploading plugin, I know there are too many plugin which does this work. But I want to do by hard-coding and by myself, not by means of a plugin)

JS:

<script>
    $(document).ready(function() {
    $(':button').click(function(){
        var formData = new FormData($('form')[0]);

        $.ajax({
            url: 'bilesenler/yaziEkle/ajaxUpload.php',  //Server script to process data
            type: 'POST',
            enctype: 'multipart/form-data',

            xhr: function() {  // Custom XMLHttpRequest
                var myXhr = $.ajaxSettings.xhr();

                if(myXhr.upload){ // Check if upload property exists
                    myXhr.upload.addEventListener('progress',progressHandlingFunction, false); // It makes progressBar full.
                }
                return myXhr;
            },

            success: function(result){
                        $("#div1").html(result);   // This works very well.
                     },
            error: function(error){
                        $("#div2").html(error);   // This is not being running after the uploading process. So there is no problem.
                   },

            // Form data
            data: formData,

            //Options to tell jQuery not to process data or worry about content-type.
            cache: false,
            contentType: false,
            processData: false
        });
    });

    function progressHandlingFunction(e){
        if(e.lengthComputable){
            $('progress').attr({value:e.loaded,max:e.total});
        }
    }
});
</script>

HTML:

<form action="../adminPaneli/yaziEkle.php" method="POST" name="addText" enctype="multipart/form-data">

    <!-- 
        There are some html codes... 
    -->

    <input type="button" id="upload" value="Upload">&nbsp;&nbsp;
    <input type="file" name="file" id="file">
    <progress></progress>

    <!-- 
        There are some html codes... 
    -->

    <div id="div1"></div><br>
    <div id="div2"></div>


    <input type="submit" name="publishArticle" value="Publish">
</form>

PHP:

<?php
if (file_exists("../kitaplik/resimler/upload/" . $_FILES["file"]["name"])){
    echo $fileName . " already exists.<br>";
}
else{
    move_uploaded_file($_FILES["file"]["tmp_name"], "../kitaplik/resimler/upload/" . $_FILES["file"]["name"]);
    echo "Stored in: " . "../kitaplik/resimler/upload/" . $_FILES["file"]["name"] . " <br>";
}
?>

When I click the Upload button, the progress bar is being full. That is, the upload process exist. Then, the server is responding the request, and the html page is showing this output:

Notice: Undefined index: file in /.../bilesenler/yaziEkle/ajaxUpload.php on line 1

Notice: Undefined index: file in /.../bilesenler/yaziEkle/ajaxUpload.php on line 5

Notice: Undefined index: file in /.../bilesenler/yaziEkle/ajaxUpload.php on line 5

Notice: Undefined index: file in /.../bilesenler/yaziEkle/ajaxUpload.php on line 6

Stored in: ../kitaplik/resimler/upload/

That is, the "success" label of $.ajax ran, not "error" label. Because, when I remove the error label in $.ajax by making its line comment, the same output appers.

Normally, I can upload image with this server side code with type of submit property. But with ajax capability, receiver of the file, $_FILE, cannot catch the file. Can anybody suggest a idea to solve this problem or any new technique?

Community
  • 1
  • 1
Hasan
  • 554
  • 1
  • 7
  • 19

1 Answers1

1

Try this..

Create "uploads" directory in root

Index.php

<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Ajax Upload and Resize with jQuery and PHP - Demo</title>
<script type="text/javascript" src="http://www.sanwebe.com/wp-content/themes/sanwebe/js/jquery-1.10.2.min.js"></script>
<script type="text/javascript" src="http://www.sanwebe.com/assets/ajax-image-upload/js/jquery.form.min.js"></script>

<script type="text/javascript">
$(document).ready(function() { 
    var options = { 
            target: '#output',   // target element(s) to be updated with server response 
            beforeSubmit: beforeSubmit,  // pre-submit callback 
            success: afterSuccess,  // post-submit callback 
            resetForm: true        // reset the form after successful submit 
        }; 

     $('#MyUploadForm').submit(function() { 
            $(this).ajaxSubmit(options);            
            // always return false to prevent standard browser submit and page navigation 
            return false; 
        }); 
}); 

function afterSuccess()
{
    $('#submit-btn').show(); //hide submit button
    $('#loading-img').hide(); //hide submit button

}

//function to check file size before uploading.
function beforeSubmit(){
    //check whether browser fully supports all File API
   if (window.File && window.FileReader && window.FileList && window.Blob)
    {

        if( !$('#imageInput').val()) //check empty input filed
        {
            $("#output").html("Are you kidding me?");
            return false
        }

        var fsize = $('#imageInput')[0].files[0].size; //get file size
        var ftype = $('#imageInput')[0].files[0].type; // get file type


        //allow only valid image file types 
        switch(ftype)
        {
            case 'image/png': case 'image/gif': case 'image/jpeg': case 'image/pjpeg':
                break;
            default:
                $("#output").html("<b>"+ftype+"</b> Unsupported file type!");
                return false
        }

        //Allowed file size is less than 1 MB (1048576)
        if(fsize>1048576) 
        {
            $("#output").html("<b>"+bytesToSize(fsize) +"</b> Too big Image file! <br />Please reduce the size of your photo using an image editor.");
            return false
        }

        $('#submit-btn').hide(); //hide submit button
        $('#loading-img').show(); //hide submit button
        $("#output").html("");  
    }
    else
    {
        //Output error to older browsers that do not support HTML5 File API
        $("#output").html("Please upgrade your browser, because your current browser lacks some new features we need!");
        return false;
    }
}

//function to format bites bit.ly/19yoIPO
function bytesToSize(bytes) {
   var sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB'];
   if (bytes == 0) return '0 Bytes';
   var i = parseInt(Math.floor(Math.log(bytes) / Math.log(1024)));
   return Math.round(bytes / Math.pow(1024, i), 2) + ' ' + sizes[i];
}

</script>
<link href="http://www.sanwebe.com/assets/ajax-image-upload/style/style.css" rel="stylesheet" type="text/css">
</head>
<body>
<div id="upload-wrapper">
<div align="center">
<h3>Ajax Image Uploader</h3>
<form action="processupload.php" method="post" enctype="multipart/form-data" id="MyUploadForm">
<input name="image_file" id="imageInput" type="file" />

<img src="images/ajax-loader.gif" id="loading-img" style="display:none;" alt="Please Wait"/>
</form>
<div id="output"></div>
</div>
</div>
<script>
$("#imageInput").change(function(){
$("#MyUploadForm").submit();
});
</script>
</body>
</html>

processupload.php

<?php
############ Configuration ##############
$thumb_square_size      = 200; //Thumbnails will be cropped to 200x200 pixels
$max_image_size         = 500; //Maximum image size (height and width)
$thumb_prefix           = "thumb_"; //Normal thumb Prefix
$destination_folder     = 'uploads/'; //upload directory ends with / (slash)
$jpeg_quality           = 90; //jpeg quality
##########################################

//continue only if $_POST is set and it is a Ajax request
if(isset($_POST) && isset($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest'){

    // check $_FILES['ImageFile'] not empty
    if(!isset($_FILES['image_file']) || !is_uploaded_file($_FILES['image_file']['tmp_name'])){
            die('Image file is Missing!'); // output error when above checks fail.
    }

    //uploaded file info we need to proceed
    $image_name = $_FILES['image_file']['name']; //file name
    $image_size = $_FILES['image_file']['size']; //file size
    $image_temp = $_FILES['image_file']['tmp_name']; //file temp

    $image_size_info    = getimagesize($image_temp); //get image size

    if($image_size_info){
        $image_width        = $image_size_info[0]; //image width
        $image_height       = $image_size_info[1]; //image height
        $image_type         = $image_size_info['mime']; //image type
    }else{
        die("Make sure image file is valid!");
    }

    //switch statement below checks allowed image type 
    //as well as creates new image from given file 
    switch($image_type){
        case 'image/png':
            $image_res =  imagecreatefrompng($image_temp); break;
        case 'image/gif':
            $image_res =  imagecreatefromgif($image_temp); break;           
        case 'image/jpeg': case 'image/pjpeg':
            $image_res = imagecreatefromjpeg($image_temp); break;
        default:
            $image_res = false;
    }

    if($image_res){
        //Get file extension and name to construct new file name 
        $image_info = pathinfo($image_name);
        $image_extension = strtolower($image_info["extension"]); //image extension
        $image_name_only = strtolower($image_info["filename"]);//file name only, no extension

        //create a random name for new image (Eg: fileName_293749.jpg) ;
        $new_file_name = $image_name_only. '_' .  rand(0, 9999999999) . '.' . $image_extension;

        //folder path to save resized images and thumbnails
        $thumb_save_folder  = $destination_folder . $thumb_prefix . $new_file_name; 
        $image_save_folder  = $destination_folder . $new_file_name;

        //call normal_resize_image() function to proportionally resize image
        if(normal_resize_image($image_res, $image_save_folder, $image_type, $max_image_size, $image_width, $image_height, $jpeg_quality))
        {
            //call crop_image_square() function to create square thumbnails
            if(!crop_image_square($image_res, $thumb_save_folder, $image_type, $thumb_square_size, $image_width, $image_height, $jpeg_quality))
            {
                die('Error Creating thumbnail');
            }

            /* We have succesfully resized and created thumbnail image
            We can now output image to user's browser or store information in the database*/
            echo '<div align="center">';
            echo '<img src="uploads/'.$thumb_prefix . $new_file_name.'" alt="Thumbnail">';
            echo '<br />';
            echo '<img src="uploads/'. $new_file_name.'" alt="Resized Image">';
            echo '</div>';
        }

        imagedestroy($image_res); //freeup memory
    }
}

#####  This function will proportionally resize image ##### 
function normal_resize_image($source, $destination, $image_type, $max_size, $image_width, $image_height, $quality){

    if($image_width <= 0 || $image_height <= 0){return false;} //return false if nothing to resize

    //do not resize if image is smaller than max size
    if($image_width <= $max_size && $image_height <= $max_size){
        if(save_image($source, $destination, $image_type, $quality)){
            return true;
        }
    }

    //Construct a proportional size of new image
    $image_scale    = min($max_size/$image_width, $max_size/$image_height);
    $new_width      = ceil($image_scale * $image_width);
    $new_height     = ceil($image_scale * $image_height);

    $new_canvas     = imagecreatetruecolor( $new_width, $new_height ); //Create a new true color image

    //Copy and resize part of an image with resampling
    if(imagecopyresampled($new_canvas, $source, 0, 0, 0, 0, $new_width, $new_height, $image_width, $image_height)){
        save_image($new_canvas, $destination, $image_type, $quality); //save resized image
    }

    return true;
}

##### This function corps image to create exact square, no matter what its original size! ######
function crop_image_square($source, $destination, $image_type, $square_size, $image_width, $image_height, $quality){
    if($image_width <= 0 || $image_height <= 0){return false;} //return false if nothing to resize

    if( $image_width > $image_height )
    {
        $y_offset = 0;
        $x_offset = ($image_width - $image_height) / 2;
        $s_size     = $image_width - ($x_offset * 2);
    }else{
        $x_offset = 0;
        $y_offset = ($image_height - $image_width) / 2;
        $s_size = $image_height - ($y_offset * 2);
    }
    $new_canvas = imagecreatetruecolor( $square_size, $square_size); //Create a new true color image

    //Copy and resize part of an image with resampling
    if(imagecopyresampled($new_canvas, $source, 0, 0, $x_offset, $y_offset, $square_size, $square_size, $s_size, $s_size)){
        save_image($new_canvas, $destination, $image_type, $quality);
    }

    return true;
}

##### Saves image resource to file ##### 
function save_image($source, $destination, $image_type, $quality){
    switch(strtolower($image_type)){//determine mime type
        case 'image/png': 
            imagepng($source, $destination); return true; //save png file
            break;
        case 'image/gif': 
            imagegif($source, $destination); return true; //save gif file
            break;          
        case 'image/jpeg': case 'image/pjpeg': 
            imagejpeg($source, $destination, $quality); return true; //save jpeg file
            break;
        default: return false;
    }
}
Deenadhayalan Manoharan
  • 5,436
  • 14
  • 30
  • 50
  • As far as I see, this code uploads image by submitting the form. I need to upload the file by not submitting the form. Because my work with form is not finishing after the uploading process. And also, I have tried the code. It didn't work. I mean, in the console there is out of subject error, and in the uploads directore there is no image. Does this code work on your machine? – Hasan Jul 22 '15 at 13:11
  • When I attempt to select an image after clicking the button on the screen, another uploading button is being appeared below on the screen. When I select the image with the new upload button below, the image is being selected, but there is no image in the uploads directory. As for the error: GET http://localhost/upload/4/images/ajax-loader.gif 404 (Not Found) As I said, this error is out of subject. – Hasan Jul 22 '15 at 13:21
  • There is two file first index.php and processupload.php then create uploads directory in root its working for me. – Deenadhayalan Manoharan Jul 22 '15 at 13:26
  • and all files put in example directory like "test". and run localhost/test – Deenadhayalan Manoharan Jul 22 '15 at 13:28
  • Interesting. I have already created processupload.php, index.php and uploads directory. But unfortunately, it doesn't work on my machine like the other ones. Let me look deeply the code. Maybe I can find any error, thereby I can focus to solve the problem. – Hasan Jul 22 '15 at 13:28
  • I did stupid error. I fixed it and it works for me too. – Hasan Jul 22 '15 at 13:46