Created
September 28, 2012 11:24
-
-
Save paulherron/3799276 to your computer and use it in GitHub Desktop.
XHR multiple image upload
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
$(document).ready(function() { | |
var fileInput = $('#ImageImage'); | |
var fileList = $('#file_list'); | |
var form = $('#ImageAdminAddForm'); | |
var fileCount = 0; | |
// The submit button might have loaded 'disabled' (e.g. if the page was refreshed half-way through an upload) so be sure to remove this. | |
$('input[type=submit]', form).removeAttr('disabled'); | |
/** | |
* Creates a thumbnail preview of the specified file, with progress bar. | |
* @param object file The selected file to upload | |
* @param int fileNumber Which number file this is in the batch upload | |
*/ | |
function createPreview(file, fileNumber) { | |
var li = document.createElement('li'), | |
div = document.createElement('div'), | |
img, | |
progressBarContainer = document.createElement('div'), | |
progressBar = document.createElement('div'), | |
reader, | |
xhr, | |
fileInfo; | |
// If the file is an image and the web browser supports FileReader, present a preview in the file list. | |
if(typeof FileReader !== 'undefined' && (/image/i).test(file.type)) { | |
img = document.createElement('img'); | |
img.title = file.name; | |
if(window.webkitURL) { | |
img.src = window.webkitURL.createObjectURL(file); | |
} else { | |
img.src = window.URL.createObjectURL(file); | |
} | |
li.appendChild(img); | |
} | |
progressBarContainer.className = 'progress_bar_container'; | |
$(progressBarContainer).attr('id', 'progress_bar_container_' + fileNumber); | |
progressBar.className = 'progress_bar'; | |
progressBarContainer.appendChild(progressBar); | |
li.appendChild(progressBarContainer); | |
$(progressBarContainer).html('Ready to upload…'); | |
fileList.append(li); | |
} | |
/** | |
* Uploads the specified file, alongside all the other fields in the form. | |
* @param object file The selected file to upload | |
* @param int fileNumber Which number file this is in the batch upload | |
*/ | |
function uploadFile(fileNumber) { | |
file = fileInput.prop('files')[ fileNumber ]; | |
console.log('uploading file ' + fileNumber); | |
progressBarContainer = $('#progress_bar_container_' + fileNumber); | |
progressBar = document.createElement('progress'); | |
progressBarContainer.html(progressBar); | |
xhr = new XMLHttpRequest(); | |
// Update the progress bar as the file uploads. | |
xhr.upload.addEventListener('progress', function (evt) { | |
if(evt.lengthComputable) { | |
percentComplete = (evt.loaded / evt.total) * 100; | |
console.log(percentComplete); | |
progressBar.max = 100; | |
progressBar.value = percentComplete; | |
} | |
}, false); | |
// Show in the progress bar when the upload is complete. | |
xhr.addEventListener('load', function () { | |
progressBarContainer.addClass('uploaded'); | |
progressBarContainer.html('<span>✓</span> Done'); | |
console.log('upload for file ' + fileNumber + ' finished'); | |
if(fileNumber < fileCount - 1) { | |
// As there are more files to upload, call the upload function again. | |
uploadFile(++fileNumber); | |
} else { | |
// As all the files were uploaded, redirect. | |
if(typeof xhr.responseText !== 'undefined') { | |
window.location = JSON.parse(xhr.responseText).redirect_url; | |
} else { | |
window.location = document.referrer; | |
} | |
} | |
}, false); | |
xhr.open('post', location.pathname + '.json'); | |
xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest'); | |
// Get the entire contents of the form, including all fields. | |
formSubmission = form.clone(true, true); | |
// This script aims to upload the images one-by-one, so if multiple images were selected they need to be removed from the submission. | |
$('#ImageImage', formSubmission).remove(); | |
formData = new FormData(formSubmission[0]); | |
// Now append the one image to be uploaded to the POST request. | |
formData.append('data[Image][image]', fileInput.prop('files')[ fileNumber ]); | |
xhr.send(formData); | |
} | |
/** | |
* Monitors for a new selection of files being made. | |
*/ | |
fileInput.change(function() { | |
if(typeof this.files !== 'undefined') { | |
fileList.empty(); | |
for(var i=0, l=this.files.length; i<l; i++) { | |
createPreview(this.files[i], i); | |
} | |
} | |
}); | |
/** | |
* Monitors for the form submit button being pressed, and uploads the files. | |
*/ | |
form.submit(function(event) { | |
fileCount = fileInput.prop('files').length; | |
if(typeof fileInput.prop('files') !== 'undefined' && fileCount) { | |
// Convey that the upload is happening by disabling the submit button and jumping to the first file in the upload list. | |
$('input[type=submit]', form).attr('disabled', 'disabled'); | |
// Scroll up to the file list to show that the upload has begun. | |
window.location.hash = 'file_list'; | |
event.preventDefault(); | |
uploadFile(0); | |
} | |
return false; | |
}); | |
/** | |
* Dynamically updates the selected="selected" attributes on <select> options when a different option is chosen. Otherwise FormData will send values for whatever was selected when the page first loaded, which is not desired. | |
*/ | |
$('select', form).change(function() { | |
newValue = $(this).val(); | |
$('option', this).removeAttr('selected'); | |
$('option[value="' + newValue + '"]', this).attr('selected', 'selected'); | |
}); | |
}); |
This helped me wrap my head around this.
SO THANKS! :)
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Practically How to Use it ?