I use this code to upload files, and this code have a progressbar. The problem with this code is that it never send me to "upload.php" after it have uploaded the file, after it reach 100% on the progressbar. (It's not my code).
The code:
// get form data for POSTing
//var vFD = document.getElementById('upload_form').getFormData(); // for FF3
var vFD = new FormData(document.getElementById('upload_form'));
// create XMLHttpRequest object, adding few event listeners, and POSTing our data
var oXHR = new XMLHttpRequest();
oXHR.upload.addEventListener('progress', uploadProgress, false);
oXHR.addEventListener('load', uploadFinish, false);
oXHR.addEventListener('error', uploadError, false);
oXHR.addEventListener('abort', uploadAbort, false);
oXHR.open('POST', 'upload.php');
oXHR.send(vFD);
The whole script
// common variables
var iBytesUploaded = 0;
var iBytesTotal = 0;
var iPreviousBytesLoaded = 0;
var iMaxFilesize = 1048576; // 1MB
var oTimer = 0;
var sResultFileSize = '';
var uploadingcanceld = "حدث خطأ أثناء تحميل الملف";
function secondsToTime(secs) { // we will use this function to convert seconds in normal time format
var hr = Math.floor(secs / 3600);
var min = Math.floor((secs - (hr * 3600))/60);
var sec = Math.floor(secs - (hr * 3600) - (min * 60));
if (hr < 10) {hr = "0" + hr; }
if (min < 10) {min = "0" + min;}
if (sec < 10) {sec = "0" + sec;}
if (hr) {hr = "00";}
return hr + ':' + min + ':' + sec;
};
function bytesToSize(bytes) {
var sizes = ['Bytes', 'KB', 'MB'];
if (bytes == 0) return 'n/a';
var i = parseInt(Math.floor(Math.log(bytes) / Math.log(1024)));
return (bytes / Math.pow(1024, i)).toFixed(1) + ' ' + sizes[i];
};
function fileSelected() {
// hide different warnings
document.getElementById('upload_response').style.display = 'none';
document.getElementById('error').style.display = 'none';
document.getElementById('error2').style.display = 'none';
document.getElementById('abort').style.display = 'none';
document.getElementById('warnsize').style.display = 'none';
// get selected file element
var oFile = document.getElementById('ufile').files[0];
// filter for image files
var rFilter = /^(image\/bmp|image\/gif|image\/jpeg|image\/png|image\/tiff)$/i;
if (! rFilter.test(oFile.type)) {
document.getElementById('error').style.display = 'block';
return;
}
// little test for filesize
if (oFile.size > iMaxFilesize) {
document.getElementById('warnsize').style.display = 'block';
return;
}
// get preview element
var oImage = document.getElementById('preview');
// prepare HTML5 FileReader
var oReader = new FileReader();
oReader.onload = function(e){
// e.target.result contains the DataURL which we will use as a source of the image
oImage.src = e.target.result;
oImage.onload = function () { // binding onload event
// we are going to display some custom image information here
sResultFileSize = bytesToSize(oFile.size);
document.getElementById('fileinfo').style.display = 'block';
document.getElementById('filename').innerHTML = 'Name: ' + oFile.name;
document.getElementById('filesize').innerHTML = 'Size: ' + sResultFileSize;
document.getElementById('filetype').innerHTML = 'Type: ' + oFile.type;
document.getElementById('filedim').innerHTML = 'Dimension: ' + oImage.naturalWidth + ' x ' + oImage.naturalHeight;
};
};
// read selected file as DataURL
oReader.readAsDataURL(oFile);
}
function startUploading() {
// cleanup all temp states
iPreviousBytesLoaded = 0;
$("#upload").animate({height:'75px'},350);
$("#loadingborders").fadeIn(1500);
$("#progress_percent").fadeIn(1500);
$("#upload_button").fadeOut(100);
$("#ufile").fadeOut(100);
document.getElementById('ufile').style.margin = '5px 0px -5px 0px';
document.getElementById('upload_response').style.display = 'none';
document.getElementById('error').style.display = 'none';
document.getElementById('error2').style.display = 'none';
document.getElementById('abort').style.display = 'none';
document.getElementById('warnsize').style.display = 'none';
document.getElementById('progress_percent').innerHTML = '';
var oProgress = document.getElementById('progress');
oProgress.style.display = 'block';
oProgress.style.width = '0px';
// get form data for POSTing
//var vFD = document.getElementById('upload_form').getFormData(); // for FF3
var vFD = new FormData(document.getElementById('upload_form'));
// create XMLHttpRequest object, adding few event listeners, and POSTing our data
var oXHR = new XMLHttpRequest();
oXHR.upload.addEventListener('progress', uploadProgress, false);
oXHR.addEventListener('load', uploadFinish, false);
oXHR.addEventListener('error', uploadError, false);
oXHR.addEventListener('abort', uploadAbort, false);
oXHR.open('POST', 'upload.php');
oXHR.send(vFD);
// set inner timer
oTimer = setInterval(doInnerUpdates, 300);
}
function doInnerUpdates() { // we will use this function to display upload speed
var iCB = iBytesUploaded;
var iDiff = iCB - iPreviousBytesLoaded;
// if nothing new loaded - exit
if (iDiff == 0)
return;
iPreviousBytesLoaded = iCB;
iDiff = iDiff * 2;
var iBytesRem = iBytesTotal - iPreviousBytesLoaded;
var secondsRemaining = iBytesRem / iDiff;
// update speed info
var iSpeed = iDiff.toString() + 'B/s';
if (iDiff > 1024 * 1024) {
iSpeed = (Math.round(iDiff * 100/(1024*1024))/100).toString() + 'MB/s';
} else if (iDiff > 1024) {
iSpeed = (Math.round(iDiff * 100/1024)/100).toString() + 'KB/s';
}
document.getElementById('speed').innerHTML = iSpeed;
document.getElementById('remaining').innerHTML = '| ' + secondsToTime(secondsRemaining);
}
function uploadProgress(e) { // upload process in progress
if (e.lengthComputable) {
iBytesUploaded = e.loaded;
iBytesTotal = e.total;
var iPercentComplete = Math.round(e.loaded * 100 / e.total);
var iBytesTransfered = bytesToSize(iBytesUploaded);
document.getElementById('progress_percent').innerHTML = iPercentComplete.toString() + '%';
document.getElementById('progress').style.width = (iPercentComplete * 4).toString() + 'px';
document.getElementById('b_transfered').innerHTML = iBytesTransfered;
if (iPercentComplete == 100) {
var oUploadResponse = document.getElementById('upload_response');
oUploadResponse.innerHTML = '<h1>Please wait...processing</h1>';
}
} else {
document.getElementById('progress').innerHTML = 'unable to compute';
}
}
function uploadFinish(e) { // upload successfully finished
var oUploadResponse = document.getElementById('upload_response');
oUploadResponse.innerHTML = e.target.responseText;
document.getElementById('progress_percent').innerHTML = '100%';
document.getElementById('progress').style.width = '400px';
document.getElementById('filesize').innerHTML = sResultFileSize;
document.getElementById('remaining').innerHTML = '| 00:00:00';
clearInterval(oTimer);
}
function uploadError(e) { // upload error
$('#errormessage').slideUp('fast', function() {
$('#errormessage').html(uploadingcanceld);
$('#errormessage').slideDown('fast');
});
clearInterval(oTimer);
}
function uploadAbort(e) { // upload abort
clearInterval(oTimer);
}
XHR is a dynamic data call, it's not a document forwarding call, meaning the reason why we have XHR to begin with is so that we DON'T want to forward a client to another page to get new content into the page. So you might want to wait on the XHR to complete the process of sending the data, acquire the results of that transfer via XHR, and based on those results do as you want.
So in essence, you are creating a virtual document client/server transfer and handshake without having to forward the client, that of which is the role XHR was created to fulfill.
Related
I'm currently implementing an upload for files. Because I've to handle huge files here and there I've started to slice files and send them in 1mb chunks which works great as long as file are <~500MB after that it seems that memory isn't freed anyone randomly and I can't figure out what I'm missing here.
Prepare chunks
var sliceCount = 0;
var sendCount = 0;
var fileID = generateUUID();
var maxChunks = 0;
var userNotified = false;
function parseFile(file)
{
var fileSize = file.size;
var chunkSize = 1024 * 1024;//64 * 1024; // bytes
var offset = 0;
var self = this; // we need a reference to the current object
var chunkReaderBlock = null;
var numberOfChunks = fileSize / chunkSize;
maxChunks = Math.ceil(numberOfChunks);
// gets called if chunk is read into memory
var readEventHandler = function (evt)
{
if (evt.target.error == null) {
offset += evt.target.result.byteLength;
sendChunkAsBinary(evt.target.result);
}
else
{
console.log("Read error: " + evt.target.error);
return;
}
if (offset >= fileSize) {
console.log("Done reading file");
return;
}
// of to the next chunk
chunkReaderBlock(offset, chunkSize, file);
}
chunkReaderBlock = function (_offset, length, _file)
{
var r = new FileReader();
var blob = _file.slice(_offset, length + _offset);
sliceCount++;
console.log("Slicecount: " + sliceCount);
r.onload = readEventHandler;
r.readAsArrayBuffer(blob);
blob = null;
r = null;
}
// now let's start the read with the first block
chunkReaderBlock(offset, chunkSize, file);
}
Send Chunks
function sendChunkAsBinary(chunk)
{
var progressbar = $("#progressbar"), bar = progressbar.find('.uk-progress-bar');
// create XHR instance
var xhr = new XMLHttpRequest();
// send the file through POST
xhr.open("POST", 'upload.php', true);
var progressHandler = function (e)
{
// get percentage of how much of the current file has been sent
var position = e.loaded || e.position;
var total = e.total || e.totalSize;
var percentage = Math.round((sendCount / maxChunks) * 100);
// set bar width to keep track of progress
bar.css("width", percentage + "%").text(percentage + "%");
}
// let's track upload progress
var eventSource = xhr.upload || xhr;
eventSource.addEventListener("progress", progressHandler);
// state change observer - we need to know when and if the file was successfully uploaded
xhr.onreadystatechange = function ()
{
if (xhr.readyState == 4)
{
if (xhr.status == 200)
{
eventSource.removeEventListener("progress", progressHandler);
if (sendCount == maxChunks && !userNotified)
{
userNotified = true;
notifyUserSuccess("Datei hochgeladen!");
setTimeout(function ()
{
progressbar.addClass("uk-invisible");
bar.css("width", "0%").text("0%");
}, 250);
updateDocList();
}
}
else
{
notifyUser("Fehler beim hochladen der Datei!");
}
}
};
var blob;
if (typeof window.Blob == "function") {
blob = new Blob([chunk]);
} else {
var bb = new (window.MozBlobBuilder || window.WebKitBlobBuilder || window.BlobBuilder)();
bb.append(chunk);
blob = bb.getBlob();
}
sendCount++;
var formData = new FormData();
formData.append("chunkNumber", sendCount);
formData.append("maxChunks", maxChunks);
formData.append("fileID", fileID);
formData.append("chunkpart", blob);
xhr.send(formData);
progressbar.removeClass("uk-invisible");
console.log("Sendcount: " + sendCount);
}
If I attach to the debugger within Visual Studio 2015 it take a bit but soon I get an OutOfMemoryException in the send function at exactly this line: blob = new Blob([chunk]);. It's all the time the same line where the exception occures.
As soon as the Exception happens I get POST [...]/upload.php net::ERR_FILE_NOT_FOUND however I still got the chunks in my php-file.
Here's a Timeline-graph of my error
What I dont understand, I'm not able to see increasing memory inside the Task-Manager (a few mb of course but not close to 16gb ram I got).
So can anyone tell me where this leak comes from? What am I missing?
In this code create only Video on chrome, i want video with Audio with one mp4/webm file. is it possible in PHP?
please give me helpful solutions.
var mediaConstraints = { audio: true, video: true };
//var isFirefox = true;
document.querySelector('#start-recording').onclick = function() {
this.disabled = true;
navigator.getUserMedia(mediaConstraints, onMediaSuccess, onMediaError);
};
document.querySelector('#stop-recording').onclick = function() {
this.disabled = true;
mediaRecorder.stop();
};
var mediaRecorder;
function onMediaSuccess(stream) {
var video = document.createElement('video');
var videoWidth = document.getElementById('video-width').value || 320;
var videoHeight = document.getElementById('video-height').value || 240;
video = mergeProps(video, {
controls: true,
id:"preview",
width: videoWidth,
height: videoHeight,
src: URL.createObjectURL(stream)
});
video.play();
//videot='2000';
videosContainer.appendChild(video);
videosContainer.appendChild(document.createElement('hr'));
mediaRecorder = new MediaStreamRecorder(stream);
mediaRecorder.mimeType = 'video/mp4'; // this line is mandatory
mediaRecorder.videoWidth = videoWidth;
mediaRecorder.videoHeight = videoHeight;
mediaRecorder.ondataavailable = function(blob) {
//alert(blob.audio);
//alert(blob.video);
// var a = document.createElement('a');
// a.target = '_blank';
// a.innerHTML = 'Open Recorded Video No. ' + (index++) + ' (Size: ' + bytesToSize(blob.size) + ') Time Length: ' + getTimeLength(timeInterval);
// a.href = URL.createObjectURL(blob);
//videosContainer.appendChild(a);
// videosContainer.appendChild(document.createElement('hr'));
var facedeteval = document.getElementById('facedetectvalue').value;
if(facedeteval !='1')
{
//alert(facedeteval);
var testuserID = document.getElementById("tuid").value;
var capId =document.getElementById("capimg").value;
//alert(capId);
var fileType = 'video'; // or "audio"
var vname = document.getElementById('sect_id').value;
var res = vname;
fileName =res;
var fileName = res+(index++)+'.mp4'; // or "wav" or "ogg"
var formData = new FormData();
formData.append(fileType + '-filename', fileName);
formData.append(fileType + '-blob', blob);
formData.append('test_uid', testuserID);
formData.append('cap_id', capId);
function xhr(url, data, callback) {
var request = new XMLHttpRequest();
request.onreadystatechange = function () {
if (request.readyState == 4 && request.status == 200) {
callback(location.href + request.responseText);
}
};
request.open('POST', url);
request.send(data);
}
xhr('save.php', formData, function (fileURL) {
alert('video save');
stopflag = '0';
document.getElementById('facedetectvalue').value = '1';
});
}
};
var timeInterval = document.querySelector('#time-interval').value;
if(timeInterval) timeInterval = parseInt(timeInterval);
else timeInterval = 5 * 1000;
// get blob after specific time interval
mediaRecorder.start(timeInterval);
document.querySelector('#stop-recording').disabled = false;
}
function onMediaError(e) {
console.error('media error', e);
}
var videosContainer = document.getElementById('videos-container');
var index = 1;
// below function via: http://goo.gl/B3ae8c
function bytesToSize(bytes) {
var k = 1000;
var sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB'];
if (bytes === 0) return '0 Bytes';
var i = parseInt(Math.floor(Math.log(bytes) / Math.log(k)),10);
return (bytes / Math.pow(k, i)).toPrecision(3) + ' ' + sizes[i];
}
// below function via: http://goo.gl/6QNDcI
function getTimeLength(milliseconds) {
var data = new Date(milliseconds);
return data.getUTCHours()+" hours, "+data.getUTCMinutes()+" minutes and "+data.getUTCSeconds()+" second(s)";
}
window.onbeforeunload = function() {
document.querySelector('#start-recording').disabled = false;
};
I am trying to upload some large files to the server using XMLHttpRequest and file.slice.
I've manage doing this with the help of documentations and other various links.
Since uploading large file is a lengthily job, i would like to provide the user with a progress bar.
After some more readings i've come across on an example that, theoretically, does exactly what i need.
By taking the sample code and adapting it to my needs i reached
var upload =
{
blobs: [],
pageName: '',
bytesPerChunk: 20 * 1024 * 1024,
currentChunk: 0,
loaded: 0,
total: 0,
file: null,
fileName: "",
uploadChunk: function (blob, fileName, fileType) {
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function () {
if (xhr.readyState == 4) {
if (xhr.responseText) {
// alert(xhr.responseText);
}
}
};
xhr.addEventListener("load", function (evt) {
$("#dvProgressPrcent").html("100%");
$get('dvProgress').style.width = '100%';
}, false);
xhr.addEventListener("progress", function (evt) {
if (evt.lengthComputable) {
var progress = Math.ceil(((upload.loaded + evt.loaded) / upload.total) * 100);
$("#dvProgressPrcent").html(progress + "%");
$get('dvProgress').style.width = progress + '%';
}
}, false);
xhr.upload.addEventListener("progress", function (evt) {
if (evt.lengthComputable) {
var progress = Math.ceil(((upload.loaded + evt.loaded) / upload.total) * 100);
$("#dvProgressPrcent").html(progress + "%");
$get('dvProgress').style.width = progress + '%';
}
}, false);
xhr.open('POST', upload.pageName, false);
xhr.setRequestHeader("Content-Type", "multipart/form-data");
xhr.setRequestHeader("X-File-Name", fileName);
xhr.setRequestHeader("X-File-Type", fileType);
xhr.send(blob);
},
upload: function (file) {
var start = 0;
var end = 0;
var size = file.size;
var date = new Date();
upload.fileName = date.format("dd.MM.yyyy_HH.mm.ss") + "_" + file.name;
upload.loaded = 0;
upload.total = file.size;
while (start < size) {
end = start + upload.bytesPerChunk;
if (end > size) {
end = size;
}
var blob = file.slice(start, end);
upload.uploadChunk(blob, upload.fileName, file.type);
start = end;
upload.loaded += start;
}
return upload.fileName;
}
};
The call is like (without the validations)
upload.upload(document.getElementById("#upload").files[0]);
My problem is that the progress event doesn't trigger.
I've tried xhr.addEventListener and with xhr.upload.addEventListener (each at a time and both at a time) for the progress event but it never triggers. The onreadystatechange and load events trigger just fine.
I would greatly appreciate help with what i am doing wrong
Update
After many attempts i've manage to simulate a progress but i've ran into another problem: Chrome's UI is not updating during the upload.
The code looks like this now
var upload =
{
pageName: '',
bytesPerChunk: 20 * 1024 * 1024,
loaded: 0,
total: 0,
file: null,
fileName: "",
uploadFile: function () {
var size = upload.file.size;
if (upload.loaded > size) return;
var end = upload.loaded + upload.bytesPerChunk;
if (end > size) { end = size; }
var blob = upload.file.slice(upload.loaded, end);
var xhr = new XMLHttpRequest();
xhr.open('POST', upload.pageName, false);
xhr.setRequestHeader("Content-Type", "multipart/form-data");
xhr.setRequestHeader("X-File-Name", upload.fileName);
xhr.setRequestHeader("X-File-Type", upload.file.type);
xhr.send(blob);
upload.loaded += upload.bytesPerChunk;
setTimeout(upload.updateProgress, 100);
setTimeout(upload.uploadFile, 100);
},
upload: function (file) {
upload.file = file;
var date = new Date();
upload.fileName = date.format("dd.MM.yyyy_HH.mm.ss") + "_" + file.name;
upload.loaded = 0;
upload.total = file.size;
setTimeout(upload.uploadFile, 100);
return upload.fileName;
},
updateProgress: function () {
var progress = Math.ceil(((upload.loaded) / upload.total) * 100);
if (progress > 100) progress = 100;
$("#dvProgressPrcent").html(progress + "%");
$get('dvProgress').style.width = progress + '%';
}
};
Update 2
I've managed to fix it and simulate a progress bar that works in chrome too.
i've updated previous code sample with the one that works.
You can make the bar 'refresh' more often by reducing the size of the chunk uploaded at a time
Tahnk you for your help
As stated in https://stackoverflow.com/a/3694435/460368, you could do :
if(xhr.upload)
xhr.upload.onprogress=upload.updateProgress;
and
updateProgress: function updateProgress(evt)
{
if (evt.lengthComputable) {
var progress = Math.ceil(((upload.loaded + evt.loaded) / upload.total) * 100);
$("#dvProgressPrcent").html(progress + "%");
$get('dvProgress').style.width = progress + '%';
}
}
There is my solution:
function addImages(id) {
var files = $("#files").prop("files");
var file = files[loopGallery];
var cList = files.length;
var fd = new FormData();
fd.append("file", file);
fd.append("galerie", id);
var xhr = new XMLHttpRequest();
xhr.open("POST", "moduls/galerie/uploadimages.php", true);
xhr.upload.onprogress = function(e) {
var percentComplete = Math.ceil((e.loaded / e.total) * 100);
$("#progress").css("display","");
$("#progressText").text((loopGallery+1)+" z "+cList);
$("#progressBar").css("width",percentComplete+"%");
};
xhr.onload = function() {
if(this.status == 200) {
$("#progressObsah").load("moduls/galerie/showimages.php?ids="+id);
if((loopGallery+1) == cList) {
loopGallery = 0;
} else {
$("#progressBar").css("width", "0%");
loopGallery++;
addImages(id);
}
}
}
if(cList > 0) {
xhr.send(fd);
}
}
I have a some code to ajax upload . its send request to my servlet and all works fine. But code contains a progress bar what i no need. Can u help me delete lines what i no need?
Another question how to refresh DIV with my content after upload files? When i use this code to send parametrs to jsp page
$.post(
"deletePoly.jsp",
{ids:ch.toString()},
function(per){
$("#WRAPlist").load("listing.jsp");
}
);
Where i gonn put line
$("#WRAPlist").load("listing.jsp");
this is upload code
var req;
function ajaxFunction()
{
var url = "Upload_Servlet";
if (window.XMLHttpRequest) // Non-IE browsers
{
req = new XMLHttpRequest();
req.onreadystatechange = processStateChange;
try
{
req.open("GET", url, true);
}
catch (e)
{
alert(e);
}
req.send(null);
}
else if (window.ActiveXObject) // IE Browsers
{
req = new ActiveXObject("Microsoft.XMLHTTP");
if (req)
{
req.onreadystatechange = processStateChange;
req.open("GET", url, true);
req.send();
}
}
}
function processStateChange()
{
* State Description
* 0 The request is not initialized
* 1 The request has been set up
* 2 The request has been sent
* 3 The request is in process
* 4 The request is complete
if (req.readyState == 4)
{
if (req.status == 200) // OK response
{
var xml = req.responseXML;
// No need to iterate since there will only be one set of lines
var isNotFinished = xml.getElementsByTagName("finished")[0];
var myBytesRead = xml.getElementsByTagName("bytes_read")[0];
var myContentLength = xml.getElementsByTagName("content_length")[0];
var myPercent = xml.getElementsByTagName("percent_complete")[0];
// Check to see if it's even started yet
if ((isNotFinished == null) && (myPercent == null))
{
document.getElementById("initializing").style.visibility = "visible";
// Sleep then call the function again
window.setTimeout("ajaxFunction();", 100);
}
else
{
document.getElementById("initializing").style.visibility = "hidden";
document.getElementById("progressBarTable").style.visibility = "visible";
document.getElementById("percentCompleteTable").style.visibility = "visible";
document.getElementById("bytesRead").style.visibility = "visible";
myBytesRead = myBytesRead.firstChild.data;
myContentLength = myContentLength.firstChild.data;
if (myPercent != null) // It's started, get the status of the upload
{
myPercent = myPercent.firstChild.data;
document.getElementById("progressBar").style.width = myPercent + "%";
document.getElementById("bytesRead").innerHTML = myBytesRead + " of " +
myContentLength + " bytes read";
document.getElementById("percentComplete").innerHTML = myPercent + "%";
// Sleep then call the function again
window.setTimeout("ajaxFunction();", 100);
}
else
{
document.getElementById("bytesRead").style.visibility = "hidden";
document.getElementById("progressBar").style.width = "100%";
document.getElementById("percentComplete").innerHTML = "Done!";
}
}
}
else
{
alert(req.statusText);
}
}
}
remove these line of codes then it will not display progressbar..
document.getElementById("initializing").style.visibility = "hidden";
document.getElementById("progressBarTable").style.visibility = "visible";
document.getElementById("percentCompleteTable").style.visibility = "visible";
document.getElementById("bytesRead").style.visibility = "visible";
myBytesRead = myBytesRead.firstChild.data;
myContentLength = myContentLength.firstChild.data;
if (myPercent != null) // It's started, get the status of the upload
{
myPercent = myPercent.firstChild.data;
document.getElementById("progressBar").style.width = myPercent + "%";
document.getElementById("bytesRead").innerHTML = myBytesRead + " of " +
myContentLength + " bytes read";
document.getElementById("percentComplete").innerHTML = myPercent + "%";
// Sleep then call the function again
window.setTimeout("ajaxFunction();", 100);
}
else
{
document.getElementById("bytesRead").style.visibility = "hidden";
document.getElementById("progressBar").style.width = "100%";
document.getElementById("percentComplete").innerHTML = "Done!";
}
I am trying to make an autosave that can be dropped into any of my forms and be "self aware" of the content in order to simulate an actual save. In addition, I want it to be able to notify the user in the event of multiple failures of the autosave. The following is the come I have come up with, but I keep getting readyState = 4 and status = 500 as a result of my XMLHttpRequest.send(). When I "normally" click save with the form, the save works perfectly fine, but this code just doesn't seem to pass the data over correctly. Every page that has this code has a setTimeout(autosave,5000) to initialize the code. Can someone point me in the right direction of what I'm doing wrong? I'm new to XMLHttpRequest objects.
For what I can tell, last_params gets "sent" with the correct data, but when I get it via the request() (using classic ASP on the other end), the value is "" (blank). I'm thinking I have an order of execution problem, I just don't know what or where.
Quick footnote: I know that there are 'similar' functions with jQuery and other frameworks, but I do not feel comfortable enough with them yet. I want to start with something "simple".
var last_params = "";
var autosave_time = 61000;
var autosave_fail_check = 5;
var max_autosave_fail_check = 5;
var response_text = "";
function autosave() {
var autosave_button_name = "save_button";
var form_action = document.getElementById("formS").action;
var form_data = document.getElementById("formS");
var all_inputs = form_data.getElementsByTagName("input");
var all_textareas = form_data.getElementsByTagName("textarea");
var params = "";
// Check all inputs for data
for (var i = 0; i < all_inputs.length; i++) {
var current_item = all_inputs[i];
if (current_item.type != "button" && current_item.type != "submit") {
if (current_item.type != "checkbox") {
params += current_item.name + "=" + current_item.value + "&";
} else {
params += current_item.name + "=" + current_item.checked + "&";
}
}
}
// check all textareas for data
for (var i = 0; i < all_textareas.length; i++) {
var current_item = all_textareas[i];
params += current_item.name + "=" + current_item.value + "&";
}
params += "autosave=1";
if (params == last_params) {
setTimeout(autosave, autosave_time);
return;
} else {
last_params = params;
}
// Setup time
var time = "";
var currentTime = new Date();
var hours = currentTime.getHours();
var minutes = currentTime.getMinutes();
var seconds = currentTime.getSeconds();
if (minutes < 10) {
minutes = "0" + minutes;
}
time = hours + ":" + minutes + ":" + seconds;
if(hours > 11){
time = time + "PM";
} else {
time = time + "AM";
}
var status = "[]";
// **************************************************
var http;
try {
// Gecko-based browsers, Safari, and Opera.
http = new XMLHttpRequest();
} catch(e) {
try {
// For Internet Explorer.
http = new ActiveXObject('Msxml2.XMLHTTP');
} catch (e) {
// Browser supports Javascript but not XMLHttpRequest.
document.getElementById(autosave_button_name).value = "Autosave NOT Available";
http = false;
}
}
http.onreadystatechange = function()
{
if (http.readyState == 4 && http.status == 200) {
autosave_fail_check = max_autosave_fail_check; // reset the fail check
}
status = " [" + http.readyState + " / " + http.status + "] ";
}
if (autosave_fail_check <= 0) {
if (autosave_fail_check == 0) {
document.getElementById(autosave_button_name).value = "Autosave FAILURE; Check Connection!";
//alert("Autosave has FAILED! Please check your connection!");
}
autosave_fail_check = -1;
} else {
autosave_fail_check--;
}
var url = form_action;
http.open("POST", url, true); // async set to false to prevent moving on without saving
http.setRequestHeader("Content-type", "multipart/form-data");
http.setRequestHeader("Content-length", params.length);
http.setRequestHeader("Connection", "close");
http.send(last_params);
response_text = http.responseText;
if (autosave_fail_check >= 0) {
document.getElementById(autosave_button_name).value = "Last Saved: " + time + " [" + autosave_fail_check + "] " + status;
} else {
autosave_fail_check = -1;
}
setTimeout(autosave, autosave_time);
} // end function autosave()