Submit form data in file upload function? - javascript

I have a working file upload with progress bar and the file is uploaded in fileUpload.php.
function fileSelected() {
var file = document.getElementById('fileToUpload').files[0];
if (file) {
var fileSize = 0;
if (file.size > 1024 * 1024)
fileSize = (Math.round(file.size * 100 / (1024 * 1024)) / 100).toString() + 'MB';
else
fileSize = (Math.round(file.size * 100 / 1024) / 100).toString() + 'KB';
document.getElementById('file-size').innerHTML = fileSize;
}
}
function uploadFile() {
var fd = new FormData();
fd.append("fileToUpload", document.getElementById('fileToUpload').files[0]);
var xhr = new XMLHttpRequest();
xhr.upload.addEventListener("progress", uploadProgress, false);
xhr.addEventListener("load", uploadComplete, false);
xhr.addEventListener("error", uploadFailed, false);
xhr.addEventListener("abort", uploadCanceled, false);
xhr.open("POST", "src/fileUpload.php");
xhr.send(fd);
}
function uploadProgress(evt) {
if (evt.lengthComputable) {
var percentComplete = Math.round(evt.loaded * 100 / evt.total);
//var loaded = 0;
if (evt.loaded > 1024 * 1024)
loaded = (Math.round(evt.loaded * 100 / (1024 * 1024)) / 100).toString() + 'MB';
else
loaded = (Math.round(evt.loaded * 100 / 1024) / 100).toString() + 'KB';
document.getElementById('procent').innerHTML = percentComplete.toString() + '%';
document.getElementById('progressNumber').style.width = percentComplete.toString() + '%';
document.getElementById('loaded').innerHTML = loaded.toString();
}
else {
document.getElementById('progressNumber').innerHTML = 'unable to compute';
}
}
HTML:
<form id="order-form" class="needs-validation" method="post" enctype="multipart/form-data" novalidate>
<!-- Lot of inpup forms -->
<div class="custom-file">
<input type="file" class="custom-file-input" id="fileToUpload" onchange="fileSelected();" name="fileToUpload" accept=".zip" required>
<span id="selected-file" class="custom-file-label" for="fileToUpload">Choose file</span>
<div class="invalid-feedback">
Please select a file.
</div>
</div>
<button id="send-button" class="btn btn-primary btn-lg btn-block" type="button" onclick="sendOrder()">Send order</button>
But I alos want to submit the form data to a file sendOrder.php
Right now I have this
function sendOrder() {
$.ajax({
type: 'post',
url: 'src/sendOrder.php',
data: $('form').serialize(),
success: function () {
}
});
uploadFile();
}
But cant I modify my fileupload (first code block) to also send the form data do sendOrder.php?
sendorder.php contains variables like this
$email = $_POST['email'];
And send the information with mail in sendOrder.php with the variables (it is like a contact form).

You should use one ajax call for this.
Change your submit button type to type='submit' and remove the onclick() attribute
$('#order-form').submit(function(e){
e.preventDefault();
var formData = new FormData(this);
$.ajax({
type: 'post',
url: 'src/sendOrder.php',
data: formData,
success: function (response) {
console.log(response);
}
});
})

Related

How do I upload images through AJAX after compressing the images?

I have an interface that allows multiple file uploads. The user dumps a set of files on the file element.
The script then sets the height, width and dpi of those images and displays them in a large thumbnail.
That all works fine. If I right-click and save an image, it is now 1600x1600 at 96 dpi. Exactly what I specified.
Now, I need to upload the images through AJAX by creating a new FileList. But how do I specify the filename and the content for the file list?
I have a hidden file element which I'll update with the new file list which will trigger the AJAX.
Here is the HTML and the javascript/jquery:
<form enctype="multipart/form-data" id="frmUploadImage">
<input name="files" type="file" id="imgUpload" class="upload" multiple accept="image/*"/>
</form>
<form enctype="multipart/form-data" id="frmSaveImage" style="display:none">
<input name="files" type="file" id="saveImages" class="upload" multiple accept="image/*"/>
</form>
<input type="button" id="saveIt" value="Save">
<script>
$(`#imgUpload`).on(`change`, function() {
const $fileUpload = $(this);
Array.from($fileUpload.get(0).files).forEach(function(f, i) {
$(`#compressResultsContainer`).append(`<div id="image_${i}_container" class="compressedImageContainer"><img id="source_${i}" style="display:none"/><img id="image_${i}" class="compressedImage" style="width: 200px; height:200px"/><canvas id="canvas_${i}" style="display:none"></canvas><div>`);
let $preview = $(`#source_${i}`);
var reader = new FileReader();
reader.addEventListener(`load`, function(e) {
$preview.attr(`src`, e.target.result);
$preview.on(`load`, function() {
console.log(`loading preview ${i}`);
compressFile(this, i);
});
}, false);
if (f) {
reader.readAsDataURL(f);
}
});
});
function compressFile(loadedData, imgNum) {
var mime_type = `image/jpeg`;
var cvs = document.getElementById(`canvas_${imgNum}`);
cvs.width = 1600;
cvs.height = 1600;
var ctx = cvs.getContext(`2d`).drawImage(loadedData, 0, 0, 1600,1600);
var newImageData = cvs.toDataURL(mime_type, 96);
var result_image_obj = new Image();
result_image_obj.src = newImageData;
$(`#image_${imgNum}`).attr(`src`, result_image_obj.src);
}
// my test function just to see if I can build new form data---
$(`#saveIt`).on(`click`, function() {
let formData = new FormData();
$(`.newCanvas`).each(function() {
let file;
const canvas =document.getElementById($(this).attr(`id`));
canvas.toBlob((blob) => {
console.log(`canvas:`, $(this).attr(`id`));
file = new File([blob], $(this).attr(`filename`), { type: `image/jpeg` });
formData.append(`savedImages`, new File([blob], $(this).attr(`filename`), { type: `image/jpeg` }));
console.log(file);
}, `image/jpeg`);
});
setTimeout(function() { console.log(formData); }, 3000);
});
</script>
I'm basically stuck on how to populate the new FileList with the proper content -- the compressed images and their filename.
You had ONE tiny issue which made nothing to work: looping through the .newCanvas elements when absolutely no element had the class. So the loop squarely didn't run.
There also is a couple "improvements" that can be done... But to have the formData populated, that was the only thing.
So I added class="newCanvas" to <canvas id="canvas_${i}" on that line:
$(`#compressResultsContainer`).append(
`<div id="image_${i}_container" class="compressedImageContainer"><img id="source_${i}" style="display:none"/><img id="image_${i}" class="compressedImage" style="width: 200px; height:200px"/><canvas id="canvas_${i}" class="newCanvas" data-name="${f.name}" style="display:none"></canvas><div>`
);
Notice that I also added a data-name to hold the file name. That information has to be carried by the canvas to later be usable in the .each() loop.
Now about a couple improvements:
You use backticks everywhere. Good practice would be to use them when really needed, like when some templating ${variable} is inside the string...
document.getElementById($(this).attr(id)) is EXACTLY the same as just this.
Except that you've made a jQuery lookup on this to get the id and then used that id to retreive the element using plain JS.
In an .each() loop, this is the element of the current loop.
Within the .toBlob() callback, $(this) no longer is the canvas element. You have to get the informations from the canvas before calling .toBlob()
You used a setTimeout() to wait for the canvas.toblob() results... That is not reliable. I suggest you to use the number of appended files in the formData and compare that with the number of .newCanvas element to process.
That comparison has to be in the canvas.toblob() callback.
So here is the code I suggest you to try.
$(`#imgUpload`).on(`change`, function () {
const $fileUpload = $(this);
Array.from($fileUpload.get(0).files).forEach(function (f, i) {
$(`#compressResultsContainer`).append(
`<div id="image_${i}_container" class="compressedImageContainer"><img id="source_${i}" style="display:none"/><img id="image_${i}" class="compressedImage" style="width: 200px; height:200px"/><canvas id="canvas_${i}" class="newCanvas" data-name="${f.name}" style="display:none"></canvas><div>`
);
let $preview = $(`#source_${i}`);
var reader = new FileReader();
reader.addEventListener(
`load`,
function (e) {
$preview.attr(`src`, e.target.result);
$preview.on(`load`, function () {
console.log(`loading preview ${i}`);
compressFile(this, i);
});
},
false
);
if (f) {
reader.readAsDataURL(f);
}
});
});
function compressFile(loadedData, imgNum) {
var mime_type = `image/jpeg`;
var cvs = document.getElementById(`canvas_${imgNum}`);
cvs.width = 1600;
cvs.height = 1600;
var ctx = cvs.getContext(`2d`).drawImage(loadedData, 0, 0, 1600, 1600);
var newImageData = cvs.toDataURL(mime_type, 96);
var result_image_obj = new Image();
result_image_obj.src = newImageData;
$(`#image_${imgNum}`).attr(`src`, result_image_obj.src);
}
// my test function just to see if I can build new form data---
$(`#saveIt`).on(`click`, function () {
let allCanvas = $(`.newCanvas`)
let canvasCount = allCanvas.length
let formData = new FormData();
allCanvas.each(function () {
let file;
const canvas = this // document.getElementById($(this).attr(`id`));
// Get the filename here
// Because inside the .toBlob callback this and $(this) no longer is the canvas
let canvasName = this.getAttribute("data-name")
canvas.toBlob((blob) => {
console.log(`canvas:`, $(this).attr(`id`));
file = new File([blob], canvasName, { type: `image/jpeg` });
formData.append(
`savedImages`,
file
);
console.log(file);
// Did we procces all canvas?
// This part is to replce your setTimeout
// So here you can call the Ajax
if(formData.getAll("savedImages").length === canvasCount){
// Just formData will print the constructor
//console.log(formData);
console.log(formData.getAll("savedImages"));
}
}, `image/jpeg`);
});
/*
setTimeout(function () {
console.log(formData);
}, 3000);
*/
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<form enctype="multipart/form-data" id="frmUploadImage">
<input name="files" type="file" id="imgUpload" class="upload" multiple accept="image/*" />
</form>
<form enctype="multipart/form-data" id="frmSaveImage" style="display:none">
<input name="files" type="file" id="saveImages" class="upload" multiple accept="image/*" />
</form>
<input type="button" id="saveIt" value="Save">
<div id="compressResultsContainer"></div>
I finally had time to get back to this yesterday. This works:
<h1>Image Maintenance</h1><br>
<input name="files" type="file" id="imgProcess" class="upload" multiple accept="image/*"/>
<div id="progressContainer">
<div id="processProgressContainer">
<progress id="processProgress" value="0" style="vertical-align: middle;"></progress>
<span id="processStatus" style="margin-left: 20px;"></span>
</div>
<div id="uploadProgressContainer" style="display:none">
<span style="width: 150px; float:left">Seasonal Upload</span>
<span style="width: 150px; float:left">.Com Upload</span>
<span style="width: 150px; float:left">Repository Upload</span><br style="clear:both"/>
<span style="width: 150px; float:left"><progress id="seasonalProgress" value="0" style="vertical-align: middle;"></progress></span>
<span style="width: 150px; float:left"><progress id="comProgress" value="0" style="vertical-align: middle;"></progress></span>
<span style="width: 150px; float:left"><progress id="repositoryProgress" value="0" style="vertical-align: middle;"></progress></span>
</div>
</div>
<input type="button" id="saveIt" value="Save">
<input type='text' class='chromeAutoInputCatcher' tabindex='-1' name='stupidChromeInputCatcher'></input>
<div id="compressResultsContainer"></div>
<script>
// #ts-nocheck
/* eslint-disable no-undef */
/* eslint-disable max-len */
/* eslint-disable no-invalid-this */
/* eslint-disable require-jsdoc */
/* jshint esversion: 8 */
let kpData;
let repositoryData;
let collection = `524`;
let skuString = `,`;
$(`#imgProcess`).on(`change`, function() {
$(`#uploadProgressContainer`).hide();
$(`#processProgressContainer`).show();
$(`#processProgress`).val(0);
kpData = new FormData();
repositoryData = new FormData();
let rootsku=``;
skuString = `,`;
$(`#compressResultsContainer`).html(``);
//at some point, let's freeze all input until we get done compressing and displaying
const $fileUpload = $(this);
const numPics = $fileUpload.get(0).files.length;
$(`#processProgress`).attr(`max`, numPics);
Array.from($fileUpload.get(0).files).every(f=> {
const thisSku = f.name.split(`-`).slice(0, 4).join(`-`);
if (!rootsku.length) {
rootsku = thisSku.split(`-`)[0];
}
const thisrootsku = thisSku.split(`-`)[0];
if (rootsku !== thisrootsku) {
alert(`found multiple root skus. Aborting`);
$(`#imgProcess`).val(``);
kpData = new FormData();
repositoryData = new FormData();
return false;
}
return true;
});
Array.from($fileUpload.get(0).files).forEach(function(f, i) {
const thisSku = f.name.split(`-`).slice(0, 4).join(`-`);
if (skuString.indexOf(thisSku) < 0) {
skuString += `${thisSku},`;
}
$(`#compressResultsContainer`).append(`<div id="image_${i}_container" class="compressedImageContainer"><img id="source_${i}" style="display:none"/><img id="image_${i}" filename="${f.name}" class="compressedImage" style="width: 200px; height:200px; float:left"/><canvas class="newCanvas" id="canvas_${i}" style="display:none" filename="${f.name}"></canvas><span style="float:left">${f.name}</span></div><br style="clear:both"/>`);
let $preview = $(`#source_${i}`);
var reader = new FileReader();
reader.addEventListener(`load`, function(e) {
$preview.attr(`src`, e.target.result);
$preview.on(`load`, function() {
createImages(this, i);
$(`#processProgress`).val($(`#processProgress`).val() + 1);
$(`#processStatus`).html(`${$(`#processProgress`).val()} of ${numPics} file: ${f.name} `).attr(`filenum`, $(`#processProgress`).val());
if ($(`#processProgress`).val() === numPics) {
getSkus(rootsku);
console.log(`done processing`);
}
});
}, false);
if (f) {
reader.readAsDataURL(f);
}
});
});
function createImages(loadedData, imgNum) {
var mime_type = `image/jpeg`;
var cvs = document.getElementById(`canvas_${imgNum}`);
var cvsName = cvs.getAttribute(`filename`);
//Create the detail version of the image
cvs.width = 800;
cvs.height = 800;
cvs.getContext(`2d`).drawImage(loadedData, 0, 0, 800, 800);
//display the image
var newImageData = cvs.toDataURL(mime_type);
var result_image_obj = new Image();
result_image_obj.src = newImageData;
$(`#image_${imgNum}`).attr(`src`, result_image_obj.src);
//convert the canvase to an uploadable file and append it to our form data
cvs.toBlob((blob) => {
let file = new File([blob], cvsName, { type: `image/jpeg` });
kpData.append(`detail`, file, cvsName);
}, `image/jpeg`,0.96);
//create the general image
cvs.width = 370;
cvs.height = 370;
cvs.getContext(`2d`).drawImage(loadedData, 0, 0, 370, 370);
cvs.toDataURL(mime_type);
cvs.toBlob((blob) => {
let file = new File([blob], cvsName, { type: `image/jpeg` });
kpData.append(`general`, file, cvsName);
}, `image/jpeg`,0.96);
//create the thumbnail
cvs.width = 240;
cvs.height = 240;
cvs.getContext(`2d`).drawImage(loadedData, 0, 0, 240, 240);
cvs.toDataURL(mime_type);
cvs.toBlob((blob) => {
let file = new File([blob], cvsName, { type: `image/jpeg` });
kpData.append(`thumb`, file, cvsName);
}, `image/jpeg`,0.96);
//create the repository image for Amazon, Zulilly, Zappos and our wholesale customers. Zullily has the greatest minimum requirements so we'll use those for everyone
cvs.width = 1600;
cvs.height = 1600;
cvs.getContext(`2d`).drawImage(loadedData, 0, 0, 1600, 1600);
cvs.toDataURL(mime_type);
cvs.toBlob((blob) => {
let file = new File([blob], cvsName, { type: `image/jpeg` });
repositoryData.append(`imgfiles`, file, cvsName);
}, `image/jpeg`, 1);
}
let uploadLocation = `/${scPcFolder}/pc/catalog/`;
saveImages = function(url, formData,server) {
data = formData;
$(`#${server}Progress`).val(0);
$.ajax({
url: url,
cache: false,
contentType: false,
processData: false,
enctype: `multipart/form-data`,
data: data,
type: `POST`,
xhr: function() {
var myXhr = $.ajaxSettings.xhr();
if (myXhr.upload) {
myXhr.upload.addEventListener(`progress`, function(e) {
if (e.lengthComputable) {
$(`#${server}Progress`).attr({
value: e.loaded,
max: e.total,
});
}
}, false);
}
return myXhr;
}
}).done(function(data) {
}).fail(function(xhr, textStatus, errorThrown) {
console.log(xhr, textStatus, errorThrown);
}).always(function() {
});
};
function parseReturn(data = ``, nonJson = { beforeData: ``, afterData: `` }) {
data = data.replace(new RegExp(`\r?\n`, `g`), ``).replace(/\t/g, ``);//.replace(/'/g, `''`);
nonJson.beforeData = data.substring(0, data.indexOf(`{`));
nonJson.afterData = data.substring(data.lastIndexOf(`}`) + 1, 99999999);
data = data.substring(data.indexOf(`{`), data.lastIndexOf(`}`) + 1);
try {
return JSON.parse(data);
} catch (e) {
console.log(`error: `, e);
console.log(data);
}
}
$(`#saveIt`).on(`click`, function() {
$(`#processProgressContainer`).hide();
$(`#uploadProgressContainer`).show();
saveImages(`ImageManagement_AJAX.asp?action=saveFiles&uploadLocation=${uploadLocation}&skuString=${skuString}&collection=${collection}`, kpData,`seasonal`);
saveImages(`https://example.com/uploadify/ImageManagement_AJAX.asp?action=saveFiles&uploadLocation=${uploadLocation}`, kpData,`com`);
saveImages(`https://example.com/Image/Upload`, repositoryData,`repository`);
});
function getSkus(rootsku) {
$.ajax({
url: `ImageManagement_AJAX.asp`,
data: { action: `getSkus`, rootsku: rootsku, collection: collection },
type: `POST`,
}).done(function(data) {
//console.log(`data`, data);
let objSkus = parseReturn(data);
objSkus.skus.forEach(function(s) {
s.sku=s.sku.split(`-`).slice(0, s.sku.split(`-`).length - 1).join(`-`);
});
let uniqueSkus = [...new Set(objSkus.skus.map((sku) => sku.sku))];
let html=``;
//make sure every sku has a primary image in this batch of files
uniqueSkus.forEach(function(s) {
if (!$(`.compressedImage[filename="${s}.jpg"]`).length) {
html += `<span style="float:left">${s}</span><span style="float:left; min-width:10px"> </span>`;
console.log(`missing file: `, s);
}
});
if (!html.length) {
html = `Success`;
} else {
html += `<br style="clear:both"/><br/>`;
}
$(`#processStatus`).html(html);
$(`#imgProcess`).val(``);
}).fail(function(xhr, textStatus, errorThrown) {
console.log(xhr, textStatus, errorThrown);
}).always(function() {
});
}
</script>

Show progressbar only when uploading a file with ajax

My problem is, that the progressbar is always visible. I want to see it only, when the upload is in progress, or its complete.
Please comment, if you want to see the php file, that uploads the file to the server.
The upload is working, the problem is only with the progressbar.
My html form:
<form method="post" id="form" enctype="multipart/form-data" action="files/import_vevo_xls.php">
<table class="form">
<tr>
<td>
<input type="file" name="fileToUpload" id="fileToUpload" onchange="fileSelected();"/>
</td>
<td>
<div id="fileName"></div>
<div id="fileSize"></div>
<div id="fileType"></div>
</td>
</tr>
</table>
<table class="form">
<tr>
<td class="last_td_no_border">
<button class="btn saveButton" name="submitButton" type="button" onclick="uploadFile()" id="importButton">Vevők importálása</button>
</td>
<div id="progress" style="display: block;width: 200px;padding: 1px 5px;margin: 1px 0;border: 1px inset #446;border-radius: 4px;">
<div id="progressNumber" style="height:5px;background: lime;"></div>
<div id="progressValue" style="text-align: center;"></div>
</div>
</tr>
</table>
</form>
And the javascript code:
var mbMaxFilesize = 5242880; // 5 MB
function fileSelected() {
/* A fajl kiválasztása után, megnézzük a nevét, kiszámítjuk a méretét és kiírjuk a típusát */
var file = document.getElementById('fileToUpload').files[0];
if (file) {
var fileSize = 0;
if (file.size > 1024 * 1024)
fileSize = (Math.round(file.size * 100 / (1024 * 1024)) / 100).toString() + 'MB';
else
fileSize = (Math.round(file.size * 100 / 1024) / 100).toString() + 'KB';
document.getElementById('fileName').innerHTML = 'Név: ' + file.name;
document.getElementById('fileSize').innerHTML = 'Méret: ' + fileSize;
document.getElementById('fileType').innerHTML = 'Típus: ' + file.type;
}
/* Megvizsgáljuk, hogy nem haladja-e meg a limitünket, az aktuálisan kiválasztott fájl mérete */
if (file.size > mbMaxFilesize) {
alert("A fájl mérete maximum 5 MB lehet.");
xhr.addEventListener("abort", uploadCanceled, false);
return false;
}
}
function uploadFile() {
/* Maga az XMLHttpRequest indítása. A fajl kivalasztasa esetén itt indítjuk meg a küldést, illetve az eventeket/figyelésüket
majd meghívjuk az upload.php szerver oldali fájlunkat */
var fd = new FormData();
fd.append("fileToUpload", document.getElementById('fileToUpload').files[0]);
var xhr = new XMLHttpRequest();
xhr.upload.addEventListener("progress", uploadProgress, false);
xhr.addEventListener("load", uploadComplete, false);
xhr.addEventListener("error", uploadFailed, false);
xhr.addEventListener("abort", uploadCanceled, false);
xhr.open("POST", "files/import_vevo_xls.php");
xhr.send(fd);
}
function uploadProgress(evt) {
if (evt.lengthComputable) {
var percentComplete = Math.round(evt.loaded * 100 / evt.total);
document.getElementById('progressNumber').style.width = percentComplete + '%'; /*grafikus kijelzésnek*/
document.getElementById('progressValue').innerHTML = percentComplete.toString() + '%'; /*érték kijelzésének*/
}
else
{
document.getElementById('progressNumber').innerHTML = 'nem kiszámithato.';
}
}
function uploadComplete(evt) {
document.getElementById('progressNumber').style.width = 100 + '%'; /*grafikus kijelzésnek*/
document.getElementById('progressValue').innerHTML = '100' + '%'; /*érték kijelzésének*/
alert(evt.target.responseText);
}
function uploadFailed(evt) {
alert("Hiba, a feltöltés sikertelen.");
}
function uploadCanceled(evt) {
alert("A feltöltést a böngészö megszakitotta.");
}
Three changes are necessary in order to make the progressbar visible during upload or when it is complete:
Change the div with id="progress":
<!--This makes the progressbar initially invisible.-->
<div id="progress" style="visibility:hidden;...>
Add following line to function uploadProgress:
<!--This makes progressbar visible during upload.-->
document.getElementById('progress').style.visibility = 'visible';
Add this tow function fileSelected:
<!--This hides progressbar if user selects another file.-->
document.getElementById('progress').style.visibility = 'hidden';

How to make HTML Progress Bar Correctly

I am trying to make a Progress Bar for the uploaded progress in my application. So far I have this
<div class="col-sm-12">
<span style="border-left:5px solid #555555; padding-left:.5em">Upload File</span>
<div style="margin-top:1em; margin-left:.8em;">
<input type="file" name="file" class="inputfile" id="group-agent-file" accept=".csv"/>
<label for="file" id="span-file-upload" class="btn btn-danger">
<span class="fa fa-upload" style="margin-right:.5em"></span>
<span id="span-file-name">Choose a file</span>
</label>
<div>
<button type="button" id="btn-group-agent-upload" class="btn btn-primary" title="Upload">Upload</button>
</div>
<div class="progress">
<div class="progress-bar progress-bar-green" role="progressbar" id="progress-bar-upload">
<span></span>
</div>
</div>
and this is my javascript
var result = event.target.result;
var data = $.csv.toObjects(result);
var length = data.length;
var count = 0;
var percent;
$.each(data, function (key, val) {
$.ajax({
xhr: function(){
var xhr = $.ajaxSettings.xhr();
xhr.upload.onprogress = function (evt) {
console.log('progress', evt.loaded / evt.total * 100);
};
},
type: "POST",
url: "IROA_StoredProcedures.asmx/Insert_Bulk_Agent",
data: JSON.stringify(val),
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function () {
count = count + 1;
percent = count / length * 100;
$("#progress-bar-upload").css("width", percent + "%");
$("#progress-bar-upload span").text(percent + "% Complete");
console.log("Finished " + count + " of " + length + " employees.");
},
error: function (XMLHttpRequest) {
alert("error in Insert_Bulk_AgentInfo()");
console.log(XMLHttpRequest);
}
});
});
it works fine but I think the html can't process enough that sometimes the width percentage is delayed. How can I do this? and what may be the drawbacks when I use setInterval.
To get upload progress in jQuery you need to attach Event-Listener to the progress event.
You can do something like this in jQuery
$.ajax({
xhr: function() {
var xhr = new window.XMLHttpRequest();
xhr.upload.addEventListener("progress", function (evt) {
if (evt.lengthComputable) {
var percentComplete = (evt.loaded / evt.total);
//Update the progress bar
}
});
return xhr;
},
type: 'POST',
url: "/upload/path",
data: { YOUR UPLOAD DATA },
success: function (data) {
}
});
This would work the same for plain js
var xhr = new XMLHttpRequest();
xhr.open('POST', "/upload/path", true);
xhr.upload.addEventListener('progress', function (event) {
if (evt.lengthComputable) {
var percentComplete = (evt.loaded / evt.total);
//Update the progress bar
}
}
xhr.onload = function (response) {
// handle success/error here
}
xhr.setRequestHeader(SET_HEADERS);
xhr.send(UPLOAD_DATA);
success function will be call when your ajax call gets completed.
You should use xhr function instead of success.
xhr: function(){
var xhr = $.ajaxSettings.xhr() ;
xhr.upload.onprogress = function(evt){
console.log('progress', evt.loaded/evt.total*100);
var percentageCompleted = evt.loaded/evt.total*100;
updateUploadPercentage(parseInt(percentageCompleted));
if(percentageCompleted == 100){
$("#p_custom_message_body").html('<p>Storing training data</p><img src="media/images/loading.gif">');
}
} ;
return xhr ;
}
After that update progress bar in another function :-
function updateUploadPercentage(progress) {
var elem = document.getElementById("progressBar");
elem.style.width = progress + '%';
elem.innerHTML = progress * 1 + '%';
}

Sharing xmlhttpObject 'progress' and 'load' Event handlers between two functions (no JQUERY)

I am uploading a video file using an API to a third party server.
I have an upload function vim.uploadVidFile which has 'progress' and 'load' event listeners. If there is internet connectivity loss, I have a second function which uploads the file from where the upload got disrupted, vim.resumeUpload. This functions shares the same 'progress' and 'load' event listeners.
The issue I have is that the 'progress', and 'load' event listeners are still registering the original size of the file to be uploaded rather than the new (originalFileSize - fileSizeAlreadyUploadedToServer). This affects my progress bar and the fact that instead of uploading from where I left off, it re-uploads the entire file again.
With reference to vim.uploadProgres I found that In the console:
console.log('ORIGINAL_e.total: '+ e.total) == console.log('adjusted_e.total: '+ e.total);
vim.uploadVidFile function:
vim.uploadVidFile = function(){
console.log('uploadVidFile()...');
// GET VIDEO FILE
var input = document.getElementById('vidInput');
var vidFile = input.files[0];
var xmh = new XMLHttpRequest;
// SET EVENT LISTENERS
xmh.upload.addEventListener('progress', vim.uploadProgres, false);
xmh.addEventListener('load', vim.uploadComplete, false);
xmh.addEventListener('error', vim.uploadError, false);
xmh.onreadystatechange = function(){
if(this.readyState == this.HEADERS_RECEIVED){
console.log('RESPONSE HEADERS: ' + xmh.getAllResponseHeaders());
}
}
xmh.open('PUT', vim.upload_link_secure);
xmh.send(vidFile);
}
vim.resumeUpload function:
vim.resumeUpload = function(stringArgument){
console.log('vim.resumeUpload() ...');
console.log('stringArgument: ' + stringArgument);
// GET VIDEO FILE
var input = document.getElementById('vidInput');
var vidFile = input.files[0];
var xmh = new XMLHttpRequest;
// SET EVENT LISTENERS
// SET EVENT LISTENERS
xmh.upload.addEventListener('progress', vim.uploadProgres, false);
xmh.addEventListener('load', vim.uploadComplete, false);
xmh.addEventListener('error', vim.uploadError, false);
xmh.onreadystatechange = function(){
if(xmh.readyState == xmh.HEADERS_RECEIVED){
console.log('VERIFY RESPONSE HEADERS222: ' + xmh.getAllResponseHeaders());
console.log('getResponseHeader(\'Content-Range\')222' + xmh.getResponseHeader("Range"));
}
}
xmh.open('PUT', vim.upload_link_secure);
xmh.setRequestHeader('Content-Range', stringArgument);
xmh.send(vidFile);
}
'progress' eventListener:
// vim.bytesUploaded - bytes already uploaded to the server
vim.uploadProgres = function(e){
console.log('bytesUploaded_CONSTANT: '+ vim.bytesUploaded);
if(vim.bytesUploaded == 0){
var percent = (e.loaded/e.total) * 100;
document.getElementById('span_fill').setAttribute('style', 'width: '+ percent + '%');
document.getElementById('p_status').innerHTML= Math.round(percent) + '%';
console.log('e.loaded: '+e.loaded);
console.log('e.total: '+e.total);
}else{
console.log('ORIGINAL_e.total: '+ e.total);
e.total = e.total - vim.bytesUploaded;
var percent = (e.loaded/e.total) * 100;
document.getElementById('span_fill').setAttribute('style', 'width: '+ percent + '%');
document.getElementById('p_status').innerHTML= Math.round(percent) + '%';
console.log('adjusted_e.total: '+ e.total);
console.log('uploadedFoFar: ' + uploadedFoFar);
}
}

display json result in div using #Ajax.beginForm

I am trying to display error message that is the response from server using Ajax.beginform in mvc4.I am getting the response message and error back from server but when I display the error in a div it displays as following
{"success":false,"OtherData":"Image must be greater Than 960 x 960"}
following is my view and controller Action
controller Action
if (img.Width < 960 && img.Height < 960)
{
return Json(new { success = false, OtherData = "Image must be greater Than 960 x 960" });
}
and my partial View is
#using (Ajax.BeginForm("UploadeImage", "ImageUpload", null, new AjaxOptions { HttpMethod = "POST", OnSuccess = "OnSuccess" }, new { enctype = "multipart/form-data", Id = "ImgUp" }))
{
#Html.AntiForgeryToken()
<div id="dialog" title="Basic dialog">
Image size must be greater than 960 x 960 and less than 20 MB
<div>
<input type="file" name="Images" id="filePhoto" />
<input type="submit" name="continue" class="btn btn-info" value="continue" />
</div>
</div>
<div class="progress progress-striped">
<div class="progress-bar progress-bar-success">0%</div>
</div>
<div id="status"></div>
<div id="Error"></div>
<div>
<img id="img" src="#" alt="Preview" width="250" height="250" />
</div>
}
<script>
function readURL(input) {
if (input.files && input.files[0]) {
var reader = new FileReader();
reader.onload = function (e) {
$('#img').attr('src', e.target.result);
}
reader.readAsDataURL(input.files[0]);
}
}
$("#filePhoto").change(function () {
readURL(this);
});
(function () {
var bar = $('.progress-bar');
var percent = $('.progress-bar');
var status = $('#status');
$('#ImgUp').ajaxForm({
beforeSend: function () {
status.empty();
var percentVal = '0%';
bar.width(percentVal)
percent.html(percentVal);
},
uploadProgress: function (event, position, total, percentComplete) {
var percentVal = percentComplete + '%';
bar.width(percentVal)
percent.html(percentVal);
},
success: function () {
var percentVal = '100%';
bar.width(percentVal)
percent.html(percentVal);
},
complete: function (xhr) {
status.html(xhr.responseText);
}
});
})();
function OnSuccess() {
if (!data.success) {
document.getElementById("#Error").innerHTML =OtherData;
}
}
Try this,
function OnSuccess() {
if (!data.success) {
$("#Error").html(data.OtherData);
}
}

Categories

Resources