Today we’re going to be creating a file uploader using HTML5 drag and drop, along with the file reader API and some PHP. We’ll also be using local storage to remember which files were uploaded by the user.
Getting Started
For this tutorial I’m using jQuery and an icon font called symbolset. If you don’t want to get symbolset you could use an alternative or just not use a symbol font all together! So first off, we need to include the appropriate files in our index.html
file:
<link rel="stylesheet" type="text/css" href="style.css" /> <link rel="stylesheet" type="text/css" href="ss-standard.css" /> <script src="jquery.js"></script> <script src="javascript.js"></script>
Next lets do the main HTML in the body:
<div id="drop-files" ondragover="return false"> <!-- ondragover for firefox --> Drop Images Here </div> <div id="uploaded-holder"> <div id="dropped-files"> <div id="upload-button"> <a href="#" class="upload"><i class="ss-upload"> </i> Upload!</a> <a href="#" class="delete"><i class="ss-delete"> </i></a> <span>0 Files</span> </div> </div> <div id="extra-files"> <div class="number"> 0 </div> <div id="file-list"> <ul></ul> </div> </div> </div> <div id="loading"> <div id="loading-bar"> <div class="loading-color"> </div> </div> <div id="loading-content">Uploading file.jpg</div> </div> <div id="file-name-holder"> <ul id="uploaded-files"> <h1>Uploaded Files</h1> </ul> </div>
There is also a little bit of simple CSS.
#drop-files { width: 400px; height: 125px; background: rgba(0,0,0,0.1); border-radius: 10px; border: 4px dashed rgba(0,0,0,0.2); padding: 75px 0 0 0; text-align: center; font-size: 2em; float: left; font-weight: bold; margin: 0 20px 20px 0; } #dropped-files { float: left; position: relative; width: 560px; height: 125px; } #upload-button { position: absolute; top: 87px; z-index: 9999; width: 210px; display: none; } #dropped-files .image { height: 200px; width: 300px; border: 4px solid #fff; position: absolute; box-shadow: 0px 0px 10px rgba(0,0,0,0.1); background: #fff; border-radius: 4px; overflow: hidden; } #upload-button .ss-upload { font-size: 0.7em; } #upload-button a { text-decoration: none; color: #fff; font-weight: bold; box-shadow: 0 0 1000px 62px rgba(255, 255, 255, 1), inset 0 -35px 40px -10px #0A9FCA; font-size: 20px; padding: 10px 20px; background-color: #4bc1e3; border-radius: 10px; } #upload-button span { display: block; width: 160px; text-align: center; margin: 20px 0 0 0; background: white; border-radius: 10px; font-size: 1.1em; padding: 4px 0; position: relative; left: -14px; } #upload-button a:hover { box-shadow: 0 0 1000px 62px rgba(255, 255, 255, 1), inset 0 -5px 40px 0px #0A9FCA; } #extra-files { display: none; float: left; position: relative; } #extra-files .number { background: rgba(0,0,0,0.6); border-radius: 4px; display: inline-block; position: relative; font-weight: bold; color: #fff; padding: 20px 30px; margin: 60px 0 0 0; cursor: pointer; font-size: 30px; } #dropped-files #upload-button .delete { padding: 7px 6px 4px 6px; border-radius: 100px; background: rgba(0,0,0,0.6); box-shadow: none; font-size: 1em; margin-left: 8px; } #dropped-files #upload-button .delete:hover { background: rgba(0,0,0,0.8); } #extra-files .number:after { position: absolute; content: " "; top: 18px; left: -40px; display: block; border: 20px solid; border-color: transparent rgba(0, 0, 0, 0.6) transparent transparent; } #extra-files #file-list { display: none; background: white; padding: 20px 0; border-radius: 5px; box-shadow: 0 0 15px rgba(0,0,0,0.1); width: 250px; top: 100px; border: 1px solid #dadada; left: -10px; left: -16px; max-height: 220px; top: 150px; position: absolute; color: #545454; } #file-list ul { overflow: scroll; padding: 0; border-top: 1px solid #dadada; max-height: 200px; width: 250px; list-style: none; border-bottom: 1px solid #dadada !important; } #file-list ul li:last-of-type { border-bottom: 0 !important; } #uploaded-holder { width: 700px; height: 250px; display: none; float: left; } #extra-files #file-list:after, #extra-files #file-list:before { position: absolute; content: " "; top: -40px; left: 40px; display: block; border: 20px solid; border-color: transparent transparent #ffffff transparent; } #extra-files #file-list:before { border-color: transparent transparent #dadada transparent; top: -41px; } #extra-files #file-list li { border-bottom: 1px solid #eee; font-weight: bold; font-size: 1.5em; padding: 10px; } #loading { display: none; float: left; width: 100%; position: relative; } #loading-bar { width: 404px; height: 40px; background: #fff; box-shadow: 0 0 15px rgba(0,0,0,0.1); border-radius: 5px; padding: 2px; } .loading-color { width: 0%; height: 100%; -webkit-transition: all 0.1s ease-in; -moz-transition: all 0.1s ease-in; -ms-transition: all 0.1s ease-in; -o-transition: all 0.1s ease-in; transition: all 0.1s ease-in; border-radius: inherit; background-color: #4edbf1; } #loading-content { position: absolute; top: 15px; font-size: 1.2em; font-weight: bold; text-align: center; width: 405px; } #file-name-holder { width: 100%; float: left; } #file-name-holder h1 { text-align: center; border-bottom: 1px solid #dadada; padding: 20px 0; font-size: 3em; margin: 0; } #uploaded-files { background: white; border-radius: 5px; box-shadow: 0 0 15px rgba(0,0,0,0.1); width: 407px; top: 100px; padding: 0; border: 1px solid #dadada; max-height: 320px; overflow: scroll; color: #545454; } #uploaded-files li { padding: 10px; border-bottom: 1px solid #eee; font-size: 1.5em; font-weight: bold; line-height: 25px; color: #545454; } #uploaded-files a { color: #1bacbf; }
jQuery
Effectively what we want to do is get the Data URI for all the images that the user drags into the drag area. Data URIs represent the data of the image. Basically, what we want to do at the simplest level is put all the data URIs the user drags into the box into an array, and post it to a PHP file. This PHP file will process the URIs and upload them to the server.
To begin, we need to initiate some variables:
$(document).ready(function() { // Makes sure the dataTransfer information is sent when we // Drop the item in the drop box. jQuery.event.props.push('dataTransfer'); var z = -40; // The number of images to display var maxFiles = 5; var errMessage = 0; // Get all of the data URIs and put them in an array var dataArray = [];
Next we need to bind a function to the drop event. This will mean when the user drops something onto the drop area we can run a function to do what we want to do. We want to support multiple file uploads so we will run each in jQuery to run a function for each file dragged into the drag area.
$('#drop-files').bind('drop', function(e) { // This variable represents the files that have been dragged // into the drop area var files = e.dataTransfer.files; // Show the upload holder $('#uploaded-holder').show(); // For each file $.each(files, function(index, file) {
Now we want to check for any errors. If the file isn’t an image, we will show a little quirky error in the drop box.
// Some error messaging if (!files[index].type.match('image.*')) { if(errMessage == 0) { $('#drop-files').html('Hey! Images only'); ++errMessage } else if(errMessage == 1) { $('#drop-files').html('Stop it! Images only!'); ++errMessage } else if(errMessage == 2) { $('#drop-files').html("Can't you read?! Images only!"); ++errMessage } else if(errMessage == 3) { $('#drop-files').html("Fine! Keep dropping non-images."); errMessage = 0; } return false; }
When the user drops an image in the drop box, the first 5 will be shown as images. All the rest will be shown as a little +8 which when clicked will show a drop down of the files uploaded. On top of the first 5 images we’ll place the upload button. To make sure the upload button is positioned correctly, we check the position based on how many files are in the dropped files area.
if($('#dropped-files > .image').length < maxFiles) { // Change position of the upload button so it is centered var imageWidths = ((220 + (40 * $('#dropped-files > .image').length)) / 2) - 20; $('#upload-button').css({'left' : imageWidths+'px', 'display' : 'block'}); }
Now we can run the file reader function. First off, push the correct data into the array and move the dropped images so they appear to be overlapping.
var fileReader = new FileReader(); // When the filereader loads initiate a function fileReader.onload = (function(file) { return function(e) { // Push the data URI into an array dataArray.push({name : file.name, value : this.result}); // Move each image 40 more pixels across z = z+40; // This is the image var image = this.result;
The rest of this function is to do with grammar and placing the images in the correct div.
// Just some grammatical adjustments if(dataArray.length == 1) { $('#upload-button span').html("1 file to be uploaded"); } else { $('#upload-button span').html(dataArray.length+" files to be uploaded"); } // Place extra files in a list if($('#dropped-files > .image').length < maxFiles) { // Place the image inside the dropzone $('#dropped-files').append('<div class="image" style="left: '+z+'px; background: url('+image+'); background-size: cover;"> </div>'); } else { $('#extra-files .number').html('+'+($('#file-list li').length + 1)); // Show the extra files dialogue $('#extra-files').show(); // Start adding the file name to the file list $('#extra-files #file-list ul').append('<li>'+file.name+'</li>'); } }; })(files[index]); // For data URI purposes fileReader.readAsDataURL(file); }); });
Next we need a function which will restart everything to its default position and value. We’ll run this when the user presses cancel or finishes an upload.
function restartFiles() { // This is to set the loading bar back to its default state $('#loading-bar .loading-color').css({'width' : '0%'}); $('#loading').css({'display' : 'none'}); $('#loading-content').html(' '); // -------------------------------------------------------- // We need to remove all the images and li elements as // appropriate. We'll also make the upload button disappear $('#upload-button').hide(); $('#dropped-files > .image').remove(); $('#extra-files #file-list li').remove(); $('#extra-files').hide(); $('#uploaded-holder').hide(); // And finally, empty the array/set z to -40 dataArray.length = 0; z = -40; return false; }
Now we need to figure out what to do when the user presses the upload button. As I mentioned, we want to pass the data to a PHP file. We’ll also show a little CSS loading bar. We’re using each again to upload each file one by one. This is where our data URI array comes into play.
$('#upload-button .upload').click(function() { // Show the loading bar $("#loading").show(); // How much each element will take up on the loading bar var totalPercent = 100 / dataArray.length; // File number being uploaded var x = 0; var y = 0; // Show the file name $('#loading-content').html('Uploading '+dataArray[0].name); // Upload each file separately $.each(dataArray, function(index, file) {
We want to post the data to a file called upload.php (create this file!). We use jQuery’s AJAX functions to accomplish this. In the callback function for the post, we’ll update the loading bar and check if the loading process is finished completely.
// Post to the upload.php file $.post('upload.php', dataArray[index], function(data) { // The name of the file var fileName = dataArray[index].name; ++x; // Change the loading bar to represent how much has loaded $('#loading-bar .loading-color').css({'width' : totalPercent*(x)+'%'}); if(totalPercent*(x) == 100) { // Show the upload is complete $('#loading-content').html('Uploading Complete!'); // Reset everything when the loading is completed setTimeout(restartFiles, 500); } else if(totalPercent*(x) < 100) { // Show that the files are uploading $('#loading-content').html('Uploading '+fileName); }
The PHP file will return some data which we must interpret. One piece of this is the name we generate for the file, and the other is whether or not the file upload was successful. This data is separated by a colon so we have to separate it into an array and use the appropriate data. We then combine all of this data and append it to the ‘uploaded files’ section.
// Show a message showing the file URL. var dataSplit = data.split(':'); if(dataSplit[1] == 'uploaded successfully') { var realData = '<li><a href="images/'+dataSplit[0]+'">'+fileName+'</a> '+dataSplit[1]+'</li>'; $('#uploaded-files').show(); $('#uploaded-files').append('<li><a href="images/'+dataSplit[0]+'">'+fileName+'</a> '+dataSplit[1]+'</li>');
Another important thing to note is we add each file to the local storage. We can then call this later so the user can still see his or her uploaded files when they leave and come back.
// Add things to local storage if(window.localStorage.length == 0) { y = 0; } else { y = window.localStorage.length; } // We set this item in the local storage window.localStorage.setItem(y, realData); } else { $('#uploaded-files').append('<li><a href="images/'+data+'. File Name: '+dataArray[index].name+'</li>'); } }); }); return false; });
The next little bit is mostly to do with aesthetics and showing the extra files drop down (when the user clicks the +.. bit after the images).
// Just some styling for the drop file container. $('#drop-files').bind('dragenter', function() { $(this).css({'box-shadow' : 'inset 0px 0px 20px rgba(0, 0, 0, 0.1)', 'border' : '4px dashed #bb2b2b'}); return false; }); $('#drop-files').bind('drop', function() { $(this).css({'box-shadow' : 'none', 'border' : '4px dashed rgba(0,0,0,0.2)'}); return false; }); // For the file list $('#extra-files .number').toggle(function() { $('#file-list').show(); }, function() { $('#file-list').hide(); }); // Restart files when the user presses the delete button $('#dropped-files #upload-button .delete').click(restartFiles);
To finish up, we append the local storage items to the uploaded data section.
// Append the localstorage the the uploaded files section if(window.localStorage.length > 0) { $('#uploaded-files').show(); for (var t = 0; t < window.localStorage.length; t++) { var key = window.localStorage.key(t); var value = window.localStorage[key]; // Append the list items if(value != undefined || value != '') { $('#uploaded-files').append(value); } } } else { $('#uploaded-files').hide(); } });
And that’s all the Javascript! The next bit is uploading the data URI to the server, and for this we need to use PHP.
PHP
The PHP isn’t particularly hard. Our PHP file will be called upload.php
. The data URI will be encoded using base 64. We have to decode it to begin with by taking apart the data URI, grabbing the data and changing it as appropriate. After that we find the mime type, create a random name, and move the file into a variable. From there we can upload the file to a server and show a success or failure message. For this particular tutorial we’re using a folder called images to store all our images in.
<?php // We're putting all our files in a directory called images. $uploaddir = 'images/'; // The posted data, for reference $file = $_POST['value']; $name = $_POST['name']; // Get the mime $getMime = explode('.', $name); $mime = end($getMime); // Separate out the data $data = explode(',', $file); // Encode it correctly $encodedData = str_replace(' ','+',$data[1]); $decodedData = base64_decode($encodedData); // You can use the name given, or create a random name. // We will create a random name! $randomName = substr_replace(sha1(microtime(true)), '', 12).'.'.$mime; if(file_put_contents($uploaddir.$randomName, $decodedData)) { echo $randomName.":uploaded successfully"; } else { // Show an error message should something go wrong. echo "Something went wrong. Check that the file isn't corrupted"; } ?>
And now we’re done! Try out the demo (I’ve disabled uploading to the server so you wont be able to access your uploaded files on this website), or you can download the files and try it yourself (everything will work in the download). I hope you’ve enjoyed this tutorial!
Support
As you’d imagine, this doesn’t work in the latest stable release of internet explorer. However, it should work fine in any other modern browser.
Webkit | Gecko | Trident | Presto |
Yes | Yes | No | Yes |
Comments
It’s awesome! And error messages are very funny. =)
Nice! Would it be possible to drag images from other browser windows?
Hi! THX, i use this script and make my upload file with php !! http://upload.bpcoders.pl/ check this out (in polish language)
Really a great tutorial. I have seen this type of Uploader in latest WordPress CMS.
great plugin but it dosn’t work in IE 9 right?
Hi!
It really great. Good base for my script.
I have 2 comments:
1, for big files (above 600kb) is not OK without hack the POST pars.
you should split the encoded file content into 800.000 characters ca.
and send the parts in separated post vars like filepart_1, filepart_2
after sending you can rebuild the file again.
2, i had problems with Firefox.
After hacking the binded drop event with this: e.originalEvent.stopPropagation(); e.originalEvent.preventDefault();
started work normally.
with best regards
Gerely
Hi can i have a code example from the post_hack?
Hello,
how can i split the post data in this script? My Files broken at ca. 600kb. I need a code example to put it in my changed code.
Can anyone help, please?
Nice plugins
Hi,
Nice plugin.
How to get the id in the url and send the informations in my database?
(sorry for my english)
For example : i want to upload several images for a product which have an id (ex: product.php?id=1).
I would like to know how can i post this informations in my database.
Thanks.
You can add the information to a database using a simple PHP query. Just create a database with the name (which is $randomName in the PHP code), and insert it into a table which has two fields (name and id). Make the ID auto incremental.
Then just have a php file called products.php that will gather the information:
Hi,
Thanks for replying so fast.
I already have two tables with a foreign key.
table 1: product with several fields : id, name, description, caracteristique.
table 2 : product_image : fields: id, id_product, url
the foreign key is product_image.id_product = product.id
I’ve tried many things but i can not set the informations in my database.
Hope you can help me cause i really love your work !
I don’t want to give up lol!
Thanks a lot
That’s ok !!
It’s working now !!
Awesome job, thank a lot Johnny.
I’m jsute modifying the css now and everythings will be ok
Hi,
Amazing plug-in, congratulations.
Another question related to variables.
I’d like to upload the images into different folders depending on the kind of image.
Can I call to a variable from upload.php for example upload.php?id=x
thanks
Amazing!!!
Very handy, and well explained. Couple of minor issues:
1. $getMime is a bad variable name. It contains the file extension, not the mime-type, so it’s misleading. It’s also named as if it’s a method, which is stylistically weird. To each their own, I guess :)
2. You do no input filtering on $_POST[‘name’] – whatever appears after the last ‘.’ character will be written to the filesystem, which isn’t ideal.
3. It’d be handy to modify the upload function to use jQuery’s serialize on a form so you could show how to associate other data with the images being uploaded (in the real world, images would likely be associated with a document ID or CSRF token, etc). Maybe outside of the scope of the tutorial, but you went and used a symbol font, so this isn’t much further :)
Briljant, baie dankie!!
Awesome tutorial! Thanks so much for it.
When i used it i found that sometimes the bit ii was dragging over wasn’t the correct bit and the site just viewed the picture in the browser. So I put this bit of code in after the dragenter bind to let them know that they weren’t in the right place
// Let them know that they aren’t in the correct dragenter zone
$(‘#drop-files’).bind(‘dragleave’, function() {
$(this).css({‘box-shadow’ : ‘none’, ‘border’ : ‘4px dashed rgba(0,0,0,0.2)’});
return false;
});
Hi,great work here,I have rebuild this for .NET C# also,here is upload.aspx
http://www.roomfortekki.com/PagesProfile.rar
Thank you very much for this tutorial and code! I really appreciated it. Now i’m working to adapt it to my needs. Is there a way to send an email when the files are uploaded?
hello, am having a prob!
GET http://localhost/CrowdFund/index.php/%22+c+%22 400 (Bad Request) jquery.js:3
Can anyone help?MayB the url for images isnt right.. please help!
am very new to coding..
How would I go about adding an upload button as well as the drag and drop part?
Hi,
What is the license for this code?
Thanks
You can use it on any project you want.
I love this image uploading script. Is there one that can handle more than just images… for instance: .pdf, .doc, and .xls files?
Awesome code!!!
I have one question. Can I post more information by jquery to upload.php??
I need pass one specific id to php. How can I do it??
How we can generate thumbnails with this code??
Great, thank you very much.
Excellent tutorial, I really like how you explain everything thoroughly. While I realize this is explicitly for images, showing how to modify for different file types would be a great addition. Also, I notice in google chrome, it’s not submitting via $_POST but via $_FORM, found that interesting.
This is awesome!! Thank you so much for making it look so simple yet affective. I have used your PHP sample.. but on my localhost it doesnt seem to be saving the files to the images folder.
However, when I specify a Hardcoded full path like “c:\Sam” it works!
I tried giving the full path of the images folder (eg: c:\inetpub\wwwroot\myapp\images) , again this doesnt work :(
Is there a write access I need to set anywhere? I have checked Read/Write/Modify prvileges for this folder. Yet I get error when using the script.
Any help will be great appreciated!
Thanks again:)
where to use the insert into sql? because i am having problems finding out where to throw it in. after following this toturial :D
i want it too throw the images into my database after uploading and not just out in nowhere. thx for replying :)
great tutorial, thanks for sharing
Just so you know, this works fine in the latest Internet Explorer. Tested in IE10 on Windows 8 x64.
thanks for sharing. I really appreciate it!
I noticed when I dragged and dropped multiple photo files into drop box, sometimes the sequence of the files is not in order.
For example, these are the files that I want to upload in sequence : DSC08481.jpg, DSC08482.jpg, DSC08483.jpg , DSC08484.jpg.
I choose all these files, drag and drop them into drop box. I use console.log() to see data URI being push into array :
console.log(file.name);
dataArray.push({name : file.name, value : this.result});
I found out the files are not in order that I expected.
It was : DSC08483.jpg, DSC08481.jpg, DSC08482.jpg , DSC08484.jpg.
Is there a way that the files being sort before it upload to server ?
Hey John sorry for the slow reply. I think this is something I looked into when I was making this and unfortunately I couldn’t find a way to do it. It might be possible if you query every image upload, put them in an array and ordered them by name, but that seems like a lot of work! I will look at updating this in the near future.
Firstly wanted to say thanks, I used this for a uni project and it was perfect. There was just one thing I wanted to ask though, is there a way to stop the browser displaying the dropped image if they miss the drop zone? I tried the bit of script that another user posted last year but it does nothing.
Thanks again.
Hey Johnny, it’s working fine until this line $.post(‘upload.php’, dataArray[index], function(data) {…}); when it hits this line it’s not working. You said.. We use jQuery’s AJAX functions to accomplish this.But it’s not working for me.I’m trying this code for asp.net Visual studio 2008.And where should i add inside the php . Reply me asap. Thanks for your help.
Well I’m not really sure, make sure the URL to index.php is correct? It’s working for me and everyone else.
Thanks for you reply. And if i want to delete all the uploaded file how to delete it.
Clear your local storage.
can I combine the drop sensor with the image holder?
Hello,
I really like the Drag and Drop File Uploader. I am having a little bit of trouble outputting the dragged file. I created an images folder to accompany the request in the PHP file, however after i hit upload and it says upload complete, I go to my image folder and there are no images in the folder. Is there a specific folder I need to put it in? Any insight or resources would be of great help. Thanks
Have you set the folders to be writable? Try setting them to 777 with chmod.
Awesome! Is it work on moz or ie browsers?
I need that the “upload” is displayed in a Div, is possible? how? can U teach me?
Dear Johnny,
Great script . It works well in my project.
It can upload, can insert into database and can move to my desire folder.
can handle more than images eg. pdf,eps ?
thanks you so much.
Dear Johnny, It’s OK now. i can upload various file type such as *.ai, *.eps, *.pdf , etc. i need only one that it can’t accept large file. i think i can solve it. thanks you so much Johnny. you have done great work.
how did you change the code too upload pdf ect?
Very interesting code. What’r the chances that once the docs are uploaded, a button can be pressed and the docs (essentially attachments) are then placed into the user’s default email client (such as Outlook) and can then be sent off to a recipient?
Hi
how can I upload other file than images?
I want too upload pdf an excel files…
pleas give me a hint or a code :o)
I changed the code as follows to enable pdf’s:
// For each file
$.each(files, function(index, file) {
// get the file name, possibly with path (depends on browser)
var filename = files[index].name;
var filetypeallowed = false;
// Use a regular expression to trim everything before final dot
var extension = filename.replace(/^.*\./, ”);
// If there is no dot anywhere in filename, we would have extension == filename,
// so we account for this possibility now
if (extension == filename) {
extension = ”;
} else {
// if there is an extension, we convert to lower case
// (N.B. this conversion will not effect the value of the extension
// on the file upload.)
extension = extension.toLowerCase();
}
switch (extension) {
case ‘jpg’:
case ‘jpeg’:
case ‘png’:
filetypeallowed = false;
break;
case ‘pdf’:
// alert(“it’s a pdf”); //used for testing purposes only
filetypeallowed = true;
break;
//for future development case ‘xls’:
// case ‘xlsx’:
// break;
default:
filetypeallowed = false;
break;
}
// Some error messaging
//original line — if (!files[index].type.match(‘image.*’)) {
if (!filetypeallowed) {
if(errMessage == 0) {
$(‘#drop-files’).html(“Hey! PDF’s only”);
++errMessage
}
else if(errMessage == 1) {
…
…
I used switch statement for future expansion to include excel and doc files.
I get a warning that I am trying to upload an image but the MIME type is application/pdf. However the file is successfully uploaded.
I think that the problem lies within $encodedData of upload.php and am working on solving this.
Hope this helps others.
I am trying to figure out a way to capture the dropped images dimensions so that I can display the uploaded image in its actual dimensions. Any suggestions?
what am I missing? I have tried the demo but nothing seems to happen–the upload just sits there. No progress bar activity. Do I need to create the images/ dir? I tried in the folder with the index.html, and on the root.
Hi Jonny,
a nice tutorial.
Can I limit the number of files? And how?
Greeting Thomas
Hi and thanks for the nice tutorial.
But how can I limit the number of images that can be uploaded at most?
Greeting Thomas
thanks for sharing! but I have a question that I have to do to add a button as an input
thanks
hi,
Thankyou for your drag and drop plugin, is good for me and all,
If any new plugin or code relating php , pls send your news letter .
Thankyou
Shashi
Hi,
Is there a way to combine this with a regular formular, and upload the images together with the formular?
but thanks for the Script, it’s amazing!
Felix
Thanks man, your tutorial help me a lot :)
Keep it up!
Пройдет или нет такой комментарий? =)