Hasan
Hasan

Reputation: 564

AJAX can't upload the image without submit event

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?

Upvotes: 0

Views: 1654

Answers (1)

Deenadhayalan Manoharan
Deenadhayalan Manoharan

Reputation: 5444

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;
    }
}

Upvotes: 1

Related Questions