drag and drop picture upload for jHtmlArea

Feb 8, 2013 at 2:46 PM
Edited Mar 23, 2013 at 7:51 AM
Hello,

I am trying to integrate an ajax "drag and drop" image upload function for jHtmlArea and got as far as having a separate "drop box" above the toolbar.

When an image file is dropped there it is uploaded and the resulting image link is pasted as html into jHtmlArea.

What would be much nicer is if one could drop the image directly into the text area.

Would anyone be able to give a hint as to how to achieve this?

The upload box is adapted from code by Eric Potvin:

http://www.bookofzeus.com/articles/drag-and-drop-upload-files-using-ajax


Here is the html page source:
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title>Test Picture Drop and Upload for jHTMLarea</title>
    <script type="text/javascript" src="scripts/jquery-1.7.2.min.js"></script>
    <script type="text/javascript" src="scripts/jquery-ui-1.7.2.custom.min.js"></script>
    <link rel="Stylesheet" type="text/css" href="style/jqueryui/ui-lightness/jquery-ui-1.7.2.custom.css" />
 <script src="scripts/bozupload.js"></script>
 <link rel="stylesheet" href="style/bozupload.css" />
    <script type="text/javascript" src="scripts/jHtmlArea-0.7.5.js"></script>
    <link rel="Stylesheet" type="text/css" href="style/jHtmlArea.css" />
</head>
<body>
    <script type="text/javascript">
        $(function() {
            $("#jhtmlarea").htmlarea({
                toolbar: [
                    ["html","bold", "italic", "underline"],
                    ["p", "h1", "h2", "h3", "h4", "h5", "h6"],
                    ["link", "unlink"],                    
                 ],
        });
   });     
    </script>
<div align=right  style="width:360px;"><section id="uploadBox">drop image<br />here</section></div>
    
<textarea id="jhtmlarea" cols="120" rows="60"><p><h3>Test H3</h3>This is some sample text to test out the <b>WYSIWYG Control</b>.</p></textarea>
        
<div id="modal">
     <div id="modalMask"></div>
     <div id="modalContent">
       <section id="uploadStatus">
         <div id="progressWrapper">
             <div id="progressBar"></div>
             <div id="progressValue">0%</div>
             <p>Processing, please wait ... <input type="button" id="closeModal" value="Close">
         </div>
        </section>
     </div>
</div>
 </body>
</html>
here is the code of the uploader.php that receives the image file on the server and returns its url:
<?php
// Script from http://coursesweb.net/ajax

$savefolder = 'context_img';        // folder for upload
$max_size = 350;            // maxim size for image file, in KiloBytes

// Allowed image types
$allowtype = array('bmp', 'gif', 'jpg', 'jpeg', 'gif', 'png');

/** Uploading the image **/
function array_implode( $glue, $separator, $array ) {
    if ( ! is_array( $array ) ) return $array;
    $string = array();
    foreach ( $array as $key => $val ) {
        if ( is_array( $val ) )
            $val = implode( ',', $val );
        $string[] = "{$key}{$glue}{$val}";
    }
    return implode( $separator, $string );
    }
    
    
$rezultat = array_implode(":","-",$_FILES);

// if is received a valid file
if (isset ($_FILES['uploadedFile'])) {
  // checks to have the allowed extension
  $type = end(explode(".", strtolower($_FILES['uploadedFile']['name'])));
  if (in_array($type, $allowtype)) {
    // check its size
    if ($_FILES['uploadedFile']['size']<=$max_size*1000) {
      // if no errors
      if ($_FILES['uploadedFile']['error'] == 0) {
        $thefile = $savefolder . "/" . $_FILES['uploadedFile']['name'];
        // if the file can`t be uploaded, return a message
        if (file_exists($thefile))
                  {//duplicate file, just return the link to the existing file
          list($iwidth, $iheight, $itype, $iattr) = getimagesize($thefile);
          $rezultat = '<br/><img src="http://www.lissfineart.com/' . $thefile . '" width=' . $iwidth . ' height=' .  $iheight . ' border="0" hspace="0" vspace="5" /><br/>' ;
                  }
        elseif (!move_uploaded_file ($_FILES['uploadedFile']['tmp_name'], $thefile)) {
          $rezultat = 'The file can`t be uploaded, try again';
        }
        else {
          // Return the img tag with uploaded image.
          list($iwidth, $iheight, $itype, $iattr) = getimagesize($thefile);
          $rezultat = '<br/><img src="http://www.lissfineart.com/' . $thefile . '" width=' . $iwidth . ' height=' .  $iheight . ' border="0" hspace="0" vspace="5" /><br/>' ;
        //  echo 'The image was successfully loaded';
        }
      }
    }
    else { $rezultat = 'The file <b>'. $_FILES['uploadedFile']['name']. '</b> exceeds the maximum permitted size <i>'. $max_size. 'KB</i>'; }
  }
  else { $rezultat = '<b>'. $_FILES['uploadedFile']['name']. '</b> is of the wrong file type (use jpg)'; }
}

// encode with 'urlencode()' the $rezultat and return it in 'onload', inside a BODY tag
echo urlencode($rezultat);
?>
and here is the javascript that does the uploading on the client side:
function closeModal() {
    'use strict';

    // Make the modal DIV invisible:
    document.getElementById('modal').style.display = 'none';

    // Remove the click handler on the close modal button:
    document.getElementById('closeModal').onclick = null;
    
} // End of closeModal() function.

function openModal() {
    'use strict';

    // Add a click handler to the close modal button:
    document.getElementById('closeModal').onclick = closeModal;
    
    // Make the modal DIV visible:
    document.getElementById('modal').style.display = 'inline-block';
    
} // End of openModal() function.


$(document).ready(function() {
  if (typeof FormData == "undefined") {
    $('#error').html('Unable to drop files').fadeIn('fast');
    $('#uploadBox').hide();
  }
  jQuery.event.props.push('dataTransfer');

  $('#uploadBox')
    .bind('dragenter', function(e) {
      $(this).addClass("active");
      e.stopPropagation();
      e.preventDefault();
    })
    .bind('dragleave', function(e) {
      $(this).removeClass("active");
      e.stopPropagation();
      e.preventDefault();
    })
    .bind('dragover', function(e) {
      e.stopPropagation();
      e.preventDefault();
    })
    .bind('drop', function(e) {
      $(this).removeClass("active");
      e.stopPropagation();
      e.preventDefault();
      var files = e.dataTransfer.files;

      var imagetype = /image.*/;

      /* Multiple Uploads */
      var xhr, provider;
      var formData = new FormData();
      var numberFiles = files.length;

    //  for(i = 0; i < numberFiles; ++i) {
        if (!files[0].type.match(imagetype)) {
          alert('Only JPG files allowed!'); // display some message
          return false;
         // continue;
        }
        if (files[0].size > 300000) {
          alert('Maximum File Size is 300KB'); // display some message
          return false;
        //  continue;
        } 
        formData.append('uploadedFile', files[0]);
      //}
      $('#error').html('').fadeOut(0);
openModal();// open modal

      $.ajax({
        cache: false,
        contentType: false,
        data: formData,
        processData: false,
        url: 'upload_zeus.php',
        type: 'POST',
        xhr: function() {
          xhr = jQuery.ajaxSettings.xhr();
          if (xhr.upload) {
            $('#uploadStatus').show();
            xhr.upload.addEventListener('progress', function (e) {
              var p = parseInt(e.loaded/e.total*100);
              $('#progressBar').css({'width':p+'%'});
              $('#progressValue').html(p+'%');
            }, false);
          }
          return xhr;
        },
        beforeSend: function() {
          $('#progressBar').css({'width':'0%'});
          $('#progressValue').html('0%');
        }, 
        complete: function(jo,textStatus) { 
               document.getElementById('modal').style.display = 'none'; //close modal
               if (textStatus!="success") alert(textStatus);
        }, 
        success: function(output) {
         // good to go
                    // decode (urldecode) the parameter which is encoded in PHP with 'urlencode'
                var rezultat = decodeURIComponent(output.replace(/\+/g,  " "));
                var NL='\n';
                        // add the value of the parameter inside tag with 'id=showimg'
                    if (rezultat.substring(0,3) == '<br') //valid picture path
                         {
                         //  pasteHTML(prevText,NL.concat(rezultat,NL));
               document.getElementById('modal').style.display = 'none'; //close modal
                           $('#jhtmlarea').htmlarea('pasteHTML', NL.concat(rezultat,NL))
                         }
                    else
                       alert(rezultat);  
        document.getElementById('modal').style.display = 'none'; //close modal
        },
        error: function(jo,textStatus, errorThrown) {
        alert(textStatus + ' Upload Error ' + errorThrown);
        document.getElementById('modal').style.display = 'none'; //close modal
        },
      });
    });


});