I am trying to upload a file by XMLHttpRequest. After uploading I am trying to show preview of the image by calling an action as a source of the image.
Here is the code sample:
var xhr = new XMLHttpRequest();
xhr.file = file;
xhr.onreadystatechange = function (e) {
if (this.readyState == 4 && xhr.status == 200) { // here I am updating the image source
document.getElementById('imagePreview').src = '#Url.Action("GetTPImaegeByName","Techpack",new { area="OMS" })';
}
};
xhr.open('post', 'someurl', false);
var fd = new FormData;
fd.append('photo', file);
xhr.send(fd);
Here #Url.Action("GetTPImaegeByName","Techpack",new { area="OMS" }) returns an image file.
For the first time the source of the image is updating and shown correctly. But if I try again to change the file the it doesn't work. Looks like the action to update the image source is not being called. Need help to solve this problem.
Related
I am using https://www.dropzone.dev/js/ to upload images with the following script:
This is working if I upload an image. However when I capture an image with my phone (and someone else has had the same problem) although I see the preview on my .dropzone area the image never uploads. I have browsed my phone and actually don't see the image I have taken so am wondering if that is the problem but has anyone else managed to get images from a camera (where they're not saved) to upload with this script? Am I missing something?
$(".dropzone").dropzone({
url: base_url+'url/save',
acceptedFiles: 'image/*',
autoProcessQueue: false,
addRemoveLinks: true,
autoDiscover: false,
uploadMultiple: false,
init: function() {
var dzClosure = this;
$('#button[name="saveBtn"]').off('click').on('click',function(e){
e.preventDefault();
e.stopPropagation();
dzClosure.processQueue();
// Reload existing layer/view on datatable
setTimeout(function(){
MyAssets.ajax.reload(); // see notes at top
},500);
$('.modal:visible').modal('hide');
});
// When sending the data add our actual form contents too - note the formdata.append is crucial
dzClosure.on('sending', function (data, xhr, formData) {
var extra = getForm($('.modal:visible'));
formData.append(key,extra[key]);
});
// On removing files - if they are already there remove them!
dzClosure.on('removedfile',function(file) {
var params = {
fileContents: JSON.stringify(file),
assetID: $('.modal:visible').find('input[name="assetID"]').val(),
};
$.post(base_url+'url/remove',params);
})
// Preload existing image
dzClosure.addCustomFile = function(){
var thisFileBit = this;
// This is getting the SOURCE clicked VIEW link ...
// But its not ready yet
setTimeout(function(){
if (typeof $('#asset'+$('.modal:visible').find('input[name="assetID"]').val()).data('contents') != 'undefined'){
var origAsset = JSON.parse(atob($('#asset'+$('.modal:visible').find('input[name="assetID"]').val()).data('contents')));
} else {
var origAsset = {};
}
var file = {
accepted: true,
status: Dropzone.QUEUED,
size: origAsset.FileSize,
upload: {},
};
// Push file to collection
thisFileBit.files.push(file);
// Emulate event to create interface
thisFileBit.emit("addedfile", file);
// Add thumbnail url
if (origAsset.PublicImagePath != '' && typeof origAsset.PublicImagePath != 'undefined'){
thisFileBit.emit("thumbnail", file, origAsset.PublicImagePath);
}
// Add status processing to file
thisFileBit.emit("processing", file);
// Add status success to file AND RUN EVENT success from response
thisFileBit.emit("success", file,{
status: "success"
},false);
// Add status complete to file
thisFileBit.emit("complete", file);
},200);
}
// Includes test file above
dzClosure.on('addedfile',function (){
setTimeout(function(){
$('.dz-size span').data('dz-size');
$('.dz-details').remove();
$('.dz-image img').each(function(){
$(this).wrap('');
})
},1000);
});
dzClosure.addCustomFile();
}
});
I've really searched for days, but couldn't find a solution:
I have an external SVG (800k) which i need to load completely before calling the following function. Someone helped me with the code to load the SVG but I cant figure out how to detect when the SVG is completely loaded. (I am not using jQuery). I need the function initialSvgSettings() to run after the SVG has finished loading completely. Where I have it right now, it just runs when the SVG starts loading but not when it has completed.
This is the code I am using to load the SVG:
// LOAD SVG
var svgOverlay = viewer.svgOverlay();
var path = "images/elementosV6.svg";
function loadSVG(path, callback) {
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function(e) {
try {
if (xhr.readyState == 4 && xhr.status == 200) {
callback(xhr.responseXML.documentElement);
initialSvgSettings();
}
} catch (e) {
console.log(e);
}
};
xhr.open("GET", path, true);
xhr.overrideMimeType("text/xml");
xhr.responseType = "document";
xhr.send();
}
loadSVG(path, function(data) {
var g = data.getElementById("elements");
svgOverlay.node().appendChild(g);
}); // FIN LOAD SVG
The answer nearest to your question would be to point out that instead of using XMLHttpRequest.onreadystatechange, you could use the .onload event handler, which is called only after the resource has been completely loaded.
But you can also simplify your code by loading the image into an offscreen <object>. Attach your callback to .onload, and with .contentDocument you can access the DOM of the SVG.
var svgContainer = document.createElement('object');
svgContainer.type = 'image/svg+xml';
svgContainer.onload = function () {
var g = svgContainer.contentDocument.getElementById("elements");
svgOverlay.node().appendChild(g);
}
svgContainer.data = 'images/elementosV6.svg';
Using MVC 4.0, I have used the following code to create a download files from the server from an ajax source (using the latest firefox):
This works fine if the output involves are textual files such as csv or txt files, however, when it comes to files like zip or xlsx, it seems the downloaded file is different from the original source (i.e. the zip generated within the server are 15K, but the one downloaded are 26K)
I have been struggling for a few days, can I ask if anyone should shred some light on why it will works for csv/text files, but not for zip or xlsx files?
Many thanks
Controller:
Public Function download(dataIn As myObject) As ActionResult
'some processing
'generated zip files and return with the full path
Dim zipFullPath = generateFiles(dataIn)
Response.Clear()
Response.ContentType = "application/zip"
Response.AddHeader("Content-Disposition", "attachment; filename=Out.zip")
Dim fileLength = New IO.FileInfo(zipFullPath).Length
'fileLength reads about 15K of data
Response.AddHeader("Content-Length", fileLength)
Response.TransmitFile(zipFullPath)
Response.End()
Return View()
End Function
JavaScript:
$.ajax({
type: "POST",
url: "reports/download",
data: jData,
contentType: "application/json; charset=utf-8",
success: function(response, status, xhr) {
// check for a filename
var filename = "";
var disposition = xhr.getResponseHeader('Content-Disposition');
if (disposition && disposition.indexOf('attachment') !== -1) {
var filenameRegex = /filename[^;=\n]*=((['"]).*?\2|[^;\n]*)/;
var matches = filenameRegex.exec(disposition);
if (matches != null && matches[1]) filename = matches[1].replace(/['"]/g, '');
}
var type = xhr.getResponseHeader('Content-Type');
var blob = new Blob([response], { type: type });
if (typeof window.navigator.msSaveBlob !== 'undefined') {
// IE workaround for "HTML7007: One or more blob URLs were revoked by closing the blob for which they were created. These URLs will no longer resolve as the data backing the URL has been freed."
window.navigator.msSaveBlob(blob, filename);
} else {
var URL = window.URL || window.webkitURL;
var downloadUrl = URL.createObjectURL(blob);
if (filename) {
// use HTML5 a[download] attribute to specify filename
var a = document.createElement("a");
// safari doesn't support this yet
if (typeof a.download === 'undefined') {
window.location = downloadUrl;
} else {
a.href = downloadUrl;
a.download = filename;
document.body.appendChild(a);
a.click();
//Here is the problem, the original is about 15k,
// but the download file is about 26K
}
} else {
window.location = downloadUrl;
}
setTimeout(function () { URL.revokeObjectURL(downloadUrl); }, 100); // cleanup
}
},
error: function (data) {
alert('Error');
}
});
Currently jQuery ajax can only process text responses, that's why your text files work but your binary files fail.
To download a non text file from ajax use the XMLHttpRequest object and specify a responseType, for instance blob or arraybuffer.
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function(){
if (this.readyState == 4 && this.status == 200){
...
var blob = this.response; //save the blob as usual
...
}
}
xhr.open('POST', 'reports/download');
xhr.setRequestHeader('Content-Type', 'application/json; charset=utf-8');
xhr.responseType = 'blob'; // the response will be a blob and not text
xhr.send(jData);
On my site I use one core/frame PHP file. If user hit one of my link (like contact, our about..etc..) the content loaded via ajax. I use the following snippet to achieve this:
var AjaxContent = function(){
var container_div = '';
var content_div = '';
return {
getContent : function(url){
$(container_div).animate({opacity:0},
function(){ // the callback, loads the content with ajax
$(container_div).load(url, //only loads the selected portion
function(){
$(container_div).animate({opacity:1});
}
);
});
},
ajaxify_links: function(elements){
$(elements).click(function(){
AjaxContent.getContent(this.href);
return false;
});
},
init: function(params){
container_div = params.containerDiv;
content_div = params.contentDiv;
return this;
}
}
}();
I need help how to integrate a preloading, so if visitors hit one of my link (for example the gallery menu) will see a little loading image, because now they see the big white nothing for long - long seconds.
Add loading image beforing ajax call and after you get response from server simply replace that image with data like the one below
function(){ // the callback, loads the content with ajax
$(container_div).html("<img src='loading.gif' />");//add image before ajax call
$(container_div).load(url, //only loads the selected portion
function(){
$(container_div).html(data);//replace image with server response data
$(container_div).animate({opacity:1});
}
Try this
var AjaxContent = function(){
var container_div = '';
var content_div = '';
return {
getContent : function(url){
$(container_div).html('Loading...'); //replace with your loading img html code
$(container_div).load(url, //only loads the selected portion
function(){
$(container_div).css({opacity:0});
$(container_div).animate({opacity:1});
});
},
ajaxify_links: function(elements){
$(elements).click(function(){
AjaxContent.getContent(this.href);
return false;
});
},
init: function(params){
container_div = params.containerDiv;
content_div = params.contentDiv;
return this;
}
}
}();
//photo - image in Blob type
//no problems with it, checked with FileReader.readAsDataURL & <img>
var form = new FormData()
form.append('file1', photo, 'image.jpg')
ajax.post(url, form, callback) //no photos uploaded
Documentation of what I am trying to do: Uploading Files to the VK Server Procedure (step 2)
So, how should I pass my blob as POST parameter?
Image of the request
A complete File Upload exampe found at Mozilla Developer Network
https://developer.mozilla.org/en-US/docs/Using_files_from_web_applications#Example.3A_Uploading_a_user-selected_file
You use FileReader.readAsBinaryString() to read the data and then XHR sendAsBinary() to push IO forward
function FileUpload(img, file) {
var reader = new FileReader();
this.ctrl = createThrobber(img);
var xhr = new XMLHttpRequest();
this.xhr = xhr;
var self = this;
this.xhr.upload.addEventListener("progress", function(e) {
if (e.lengthComputable) {
var percentage = Math.round((e.loaded * 100) / e.total);
self.ctrl.update(percentage);
}
}, false);
xhr.upload.addEventListener("load", function(e){
self.ctrl.update(100);
var canvas = self.ctrl.ctx.canvas;
canvas.parentNode.removeChild(canvas);
}, false);
xhr.open("POST", "http://demos.hacks.mozilla.org/paul/demos/resources/webservices/devnull.php");
xhr.overrideMimeType('text/plain; charset=x-user-defined-binary');
reader.onload = function(evt) {
xhr.sendAsBinary(evt.target.result);
};
reader.readAsBinaryString(file);
}