I have renamed my uploaded file on server, when i try to delete my image through dropzone.js the file does not get deleted because it is renamed.
var myDropzone = new Dropzone("div#dropzoneFileUpload", {
addRemoveLinks: true,
url: baseUrl+"/img/upload/store",
params: {
_token: token,
},
success: function (data, textStatus, XmlHttpRequest){
},
removedfile: function(file) {
var name = file.upload.filename;
jQuery.ajax({
headers: {
'X-CSRF-TOKEN': jQuery('meta[name="_token"]').attr('content')
},
type: 'POST',
url: '{{ url("delete") }}',
data: {filename: name},
success: function (data){
console.log("File has been successfully removed!!");
},
error: function(e) {
console.log(e);
}});
var fileRef;
return (fileRef = file.previewElement) != null ?
fileRef.parentNode.removeChild(file.previewElement) : void 0;
},
});
I propose the following:
In the success method, you should be getting the uploaded file back as the first argument (what you currently have as data) and the second argument would be the new name you send back (what you currently have as textStatus).
With this, you could loop the current files in the Dropzone, finding the the correct file out of the list based on the file you get back as a first argument in the response, and then change its name accordingly. So that when you press delete, it will have the right name
Please consider the following modified pseudo code which assumes you're sending back the new file name from the server.
var myDropzone = new Dropzone("div#dropzoneFileUpload", {
addRemoveLinks: true,
url: baseUrl+"/img/upload/store",
params: {
_token: token,
},
success: function (fileSentToServer, newFileName){
// Access the current files in the list/dropzone
var fileList = myDropzone.files;
// Loop over
fileList.forEach(file => {
//Find the corresponding file in the list you just uploaded
if(file.name == fileSentToServer.name) {
//Rename it
file.name = newFileName
}
})
},
removedfile: function(file) {
// This name should now be the renamed version
var name = file.upload.filename;
jQuery.ajax({...
},
});
It's also possible you may not even need the loop if the file param returned in the success method is a direct reference to the file in the file list.
Related
I have tried all possible ways mentioned in this Solution, however didn't have any progress. Please help.
So my ajax request is as below:
function photoUploadConfirmed() {
event.preventDefault();
var files = $("#image")[0].files;
var formData = new FormData();
formData.append("file", files[0]);
console.log(files); // I just check here and in browser I can see file name and size
console.log(formData); // I expect to see the same here, but here it almost shows empty
$.ajax({
type: "POST",
url: "/Account/ChangeProfilePicture",
data: { image: formData }, // In the controller it receives IFormFile image
processData: false,
contentType: false,
success: function () {
console.log("Done");
$("#profilePhoto").val('');
$("#profPicUploadConfirm").attr("disabled", true);
},
error: function (errorMessage) {
console.log(errorMessage);
}
});
}
The ajax post request gets received by the controller's action, however the IFormFile image is always null.
[HttpPost]
public async Task<IActionResult> ChangeProfilePicture(IFormFile image)
{
// I do save here the image in the folder, but problem is that image==null
}
The ajax post request gets received by the controller's action,
however the IFormFile image is always null.
When the file is uploaded by formData append, the name at this time should be the same as "image" of the receiving parameter in action:
formData.append("image", files[0]);
And because you only need to pass the IFormFile to the action, in the data parameter of ajax, you only need to put the formData which appends the file named Image to it:
data: formData,
Change your js as follow:
function photoUploadConfirmed() {
event.preventDefault();
var files = $("#image")[0].files;
var formData = new FormData();
formData.append("image", files[0]);
console.log(files); // I just check here and in browser I can see file name and size
console.log(formData); // I expect to see the same here, but here it almost shows empty
$.ajax({
type: "POST",
url: "/Account/ChangeProfilePicture",
data: formData, // In the controller it receives IFormFile image
processData: false,
contentType: false,
success: function () {
console.log("Done");
$("#profilePhoto").val('');
$("#profPicUploadConfirm").attr("disabled", true);
},
error: function (errorMessage) {
console.log(errorMessage);
}
});
}
Here is the test result:
I had this same issue and even after updating the changes as suggested in previous answer, it didn't work for me.
Finally found the solution :
formData.append("fileInfo", fileInfo, "uploadedfile"); // uploadedfile is file name which at compile time converts to FormFile in Action method
I have a form with id: formC, on submit i call ajax:
var datiForm = new FormData();
var pos = [];
var i = 0;
posizioni.each(function () {
if($(this).find("input[type=checkbox]").is(":checked")){
pos[i] = $(this).find("input[type=checkbox]").data("id");
i++;
}
});
datiForm.append("nome",nome.val());
datiForm.append("cognome",cognome.val());
datiForm.append("email",email.val());
datiForm.append("telefono",telefono.val());
datiForm.append("dataNascita",dataNascita.val());
datiForm.append("titolo",titolo.val());
datiForm.append("ruolo",ruolo.find(":selected").data("ruolo"));
datiForm.append("sede",sede.find(":selected").data("sede"));
datiForm.append("posizione",pos);
datiForm.append("cvFile",$("#cvFile")[0].files[0]);
$.ajax({
type: "POST",
data: {datiForm: datiForm},
url: "saveCandidate.php",
processData: false,
contentType: false,
success: function (data) {
console.log(data);
},
error: function (data) {
var position = data;
}
});
I have a problem, on server $datiForm = $_POST["datiForm"]; is null why?
Moreover i have input file where i can select file pdf. I put it in FormData:
datiForm.append("cvFile",$("#cvFile")[0].files[0]);
Now on server i want to take file from $datiForm and save it into mysql as Blob is possible?
You specified the data field incorrectly, it should be just the form data object
data: datiForm,
also the way you add posizione is not going to work, each entry in yrh array has to be added individually
posizioni.each(function () {
if($(this).find("input[type=checkbox]").is(":checked")){
datiForm.append("posizione["+i+"]", $(this).find("input[type=checkbox]").data("id"));
i++;
}
});
Now on server i want to take file from $datiForm and save it into mysql as Blob is possible?
Yes
You'll need to specify the 'contentType' attribute to 'multipart/form-data' in order to upload files.
I have a JSON File, giving by vendor
{"html": "\n<link href=\"//apply.fundingoptions.com/static/msmclone/css/oembed-v3.css\" rel=\"stylesheet\">\n<script type=\"text/javascript\">\n var __raconfig = __raconfig || {};\n __raconfig.uid = '53302e56328ff';\n __raconfig.action = 'track';\n (function () {\n var ra = document.createElement('script');\n ra.type = 'text/javascript';\n ra.src = ('https:'==document.location.protocol?'https://':'http://')\n +'www.ruleranalytics.com/lib/1.0/ra-bootstrap.min.js';\n var s = document.getElementsByTagName('script')[0];\n s.parentNode.insertBefore(ra, s);\n }());\n</script>\n\n<div id=\"oembed-widget-container\" class=\"oembed-widget-container\">\n <div class=\"callout\">Initialising Finance Finder...</div>\n</div>\n<script type=\"text/javascript\">\n \n var widget_affiliate_id = 10;\n \n \n var widget_continue_url = \"//apply.fundingoptions.com/continue/\";\n \n \n var widget_submission_url = \"//apply.fundingoptions.com/oembed/submit/\";\n \n \n var widget_match_url = \"//apply.fundingoptions.com/match/\";\n \n \n var widget_title = \"Your funding options\";\n \n</script>\n<script src=\"//apply.fundingoptions.com/static/oembed/oembed-v4.js\"></script>\n\n",
"title": "Funding Options Finance Finder",
"version": 0,
"type": "rich",
"width": 500,
"height": 400
}
and I am parsing it on a webpage using this method
$.ajax({
type: 'GET',
url: 'json/data.json',
data: { get_param: 'value' },
dataType:'json',
success: function (data) {
var names = data
$('#summary').html(data.html);
}
});
But in the end , its show something like that on webpage:
as I am implementing it first time , I am not sure its my bad or json is corrupt or what else.
Looks like this is a Cross Origin Resource Sharing issue.
https://en.wikipedia.org/wiki/Cross-origin_resource_sharing
Check your browser console and look at the error you are getting when you try to load the page. It should say something similar to:
XMLHttpRequest cannot load http://apply.fundingoptions.com/match/. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'null' is therefore not allowed access.
Because the data you are requesting is not on the same server as you you are being denied access.
It looks like the error is happening when the following request is made in the oembed-v4.js library:
jQuery.ajax({
url: that.match_url,
type: 'POST',
data: postData,
success: function(data, textStatus, jqXHR) {
that.data = data;
if (data['next_question'] == null) {
that.showActions();
that.$spinnerElement.removeClass('fa-cog');
that.$spinnerElement.addClass('fa-check');
} else {
that.drawQuestion();
}
},
error: function(jqXHR, textStatus, errorThrown) {
that.displayError();
},
complete: function() {
that.toggleSpinner(false);
}
});
The vendor may need to enable Cross Origin Resource Sharing on their end from your domain.
Here is a working example of the jQuery Ajax call:
$.ajax({
url: 'https://jsonplaceholder.typicode.com/posts/1',
dataType:'json',
success: function (resp) {
console.log(resp)
var names = resp.title
$('#summary').html(names);
},
error: function (resp) {
console.log('error')
}
});
You can edit this to match your data. Make sure that the url is correct, you can try:
'./json/data.json'
You JSON is parsed correctly according to: https://jsonlint.com/
So it must be the URL.
I read this: https://github.com/enyo/dropzone/wiki/Set-URL-dynamically but i dont got success... :(
I have 1 form...
And i send the inputs with ajax.
The ajax returns the new id of user. in this moment i want to change de url dropzone for to set path to id of the new user.
$.ajax({
type: "POST",
url: "class/inserir.php?funcao=teste",
data: formdata,
dataType: "json",
success: function(json){
if(json.sucesso=="sim"){
alert("Wait! Sending Pictures.");
this.options.url = "class/upload_img.php?"+json.id;
myDropzone.processQueue();
}else{
location.href="home.php?ir=cad_animal&cad=nao&erro="+json.erro;
}
}
});
var myDropzone = new Dropzone("#imagens", {
url: "class/upload_imgteste.php",
paramName: "file", // The name that will be used to transfer the file
maxFilesize: 1, // MB
addRemoveLinks : true,
dictResponseError: "Não foi possível enviar o arquivo!",
autoProcessQueue: false,
thumbnailWidth: 138,
thumbnailHeight: 120,
});
sorry for my bad english!
Thanks for all.
You may add a function on dropzone's "processing" event listener.
Dropzone.options.myDropzone = {
init: function() {
this.on("processing", function(file) {
this.options.url = "/some-other-url";
});
}
};
Here is the link where I got the code and it works for me: https://github.com/enyo/dropzone/wiki/Set-URL-dynamically
change this
this.options.url = "class/upload_img.php?"+json.id;
to this
myDropzone.options.url = "class/upload_img.php?"+json.id;
Does that work?
New answer for an old question only because I found this answer and the link to the dropzone wiki and didn't like it. Modifying the options of the plugin multiple times like that seems very wrong.
When dropzone uses some options it runs it through a resolveOption function passing in a files array. In the current branch you can define a function for the options: method, url and timeout.
Here's a complete working example including delaying for the ajax:
Dropzone.autoDiscover = false;
const doStuffAsync = (file, done) => {
fetch('https://httpbin.org/get').then((response) => {
file.dynamicUploadUrl = `https://This-URL-will-be-different-for-every-file${Math.random()}`
done();//call the dropzone done
})
}
const getMeSomeUrl = (files) => {
return `${files[0].dynamicUploadUrl}?sugar&spice`;
}
let myDropzone = new Dropzone("#my-awesome-dropzone", {
method: "put",
accept: doStuffAsync,
url: getMeSomeUrl
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/dropzone/5.4.0/min/dropzone.min.js"></script>
<link rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/dropzone/5.4.0/min/dropzone.min.css">
<form action="/file-upload" class="dropzone" id="my-awesome-dropzone">
</form>
If you need to change the URL dropzone posts to dynamically for each file, you can use the processingfile event and change the options.url.
<form id="my-dropzone" action="/some-url" class="dropzone"></form>
<script>
Dropzone.options.myDropzone = {
init: function() {
this.on("processing", function(file) {
this.options.url = "/some-other-url";
});
}
};
</script>
Another way that worked for me (accept event callback):
$('div#dropzone').dropzone({
options...,
accept: function (file, done) {
this.options.url = 'the url you want';
}
});
BlueWater86's answer didn't work for me. But I agree that changing myDropzone.options.url each time is bad practice, and it actually doesn't work if you are dragging a lot of files into the uploader at the same time.
I wrote the following code and it works well for uploading one file at time and for many at a time. I'm using Backblaze B2 but it should also work for S3.
myDropzone.on('addedfile', function(file) {
options = {
filename: file.name,
type: file.type,
_: Date.now()
};
// Make the request for the presigned Backblaze B2 information, then attach it
$.ajax({
url: '/presign_b2',
data: options,
type: 'GET',
success: function(response){
file.dynamicUrl = response['url'];
myDropzone.enqueueFile(file);
}
});
});
myDropzone.on('sending', function(file, xhr) {
xhr.open("PUT", file.dynamicUrl); // update the URL of the request here
var _send = xhr.send;
xhr.send = function() {
_send.call(xhr, file);
}
});
The problem is very simple: i have to download a file when i submit a form, it's an ajax call when the form is submitted which lets me build a file with the data taken from the form, server side, and then send it as a link to an alert. The fact is that my boss want the file to be downloaded directly and not through a link in an alert. So i had to make sure that the file is available server side through tornado(web):
self.set_header('Content-Type', 'application/octet-stream')
self.set_header('Content-Disposition', 'attachment; filename=clients_counter.zip')
with open("static/clients_counter.zip", 'r') as f:
while True:
data = f.read()
if not data:
break
self.write(data)
self.finish()
The server side code seems to work fine, but the client side (extjs4.1) is really a nightmare. This is how my ajax call looks like now, and it doesn't work:
Ext.Ajax.request({
method : "GET",
url : 'http://whatever.com/count?client='+client+'&start='+start+'&end='+end,
timeout : 30000,
success :
function (response) {
//Ext.Msg.alert(response.responseText);
desktop.getWindow('count-win').doClose();
return response;
}//handler,
failure :
function(response) {
alert("Wrong request");
}});
After reading on various sources from Ext JS forum and here in stackoverflow, below is the approach I've chosen (using Ext JS version 4.2.1):
downloadFile: function(config){
config = config || {};
var url = config.url,
method = config.method || 'POST',// Either GET or POST. Default is POST.
params = config.params || {};
// Create form panel. It contains a basic form that we need for the file download.
var form = Ext.create('Ext.form.Panel', {
standardSubmit: true,
url: url,
method: method
});
// Call the submit to begin the file download.
form.submit({
target: '_blank', // Avoids leaving the page.
params: params
});
// Clean-up the form after 100 milliseconds.
// Once the submit is called, the browser does not care anymore with the form object.
Ext.defer(function(){
form.close();
}, 100);
}
I had a similar problem trying to download an Excel File in an Ajax call I solved it this way:
Make a standard sumbit instead of Ajax.
var form = Ext.create('Ext.form.Panel', { // this wolud be your form
standardSubmit: true, // this is the important part
url: '../ObtenerArchivoAdjuntoServlet'
});
form.submit({
params: {
nombreArchivo: nombreArchivo
}
});
After this you would be able return the desired file.
After extracting/reading many posts, I managed to get this simple method to work..
Ext.create('Ext.form.Panel', {
renderTo: Ext.getBody(),
standardSubmit: true,
url: 'URL'
}).submit({params: {'PARAM1': param1, 'PARAM2': param2}});
I think you can take a much easier solution. Forget about the ajax, and just get plain old js to open the file for you:
window.open('http://whatever.com/count?client='+client+'&start='+start+'&end='+end)
This will open a new tab and start the download from there.
The following code used to download the file using extjs 5 or 6. Add the following code to method and invoke this for button action. This downloads the file directly insteadof opening in new tab.
use an iframe like this:
/**
* prints the file
*/
printReport: function () {
var url = 'downloadURL';
Ext.Ajax.request({
url: url,
method: 'GET',
autoAbort: false,
success: function(result) {
if(result.status == 204) {
Ext.Msg.alert('Empty Report', 'There is no data');
} else if(result.status == 200) {
Ext.DomHelper.append(Ext.getBody(), {
tag: 'iframe',
frameBorder: 0,
width: 0,
height: 0,
css: 'display:none;visibility:hidden;height:0px;',
src: url
});
}
},
failure: function() {
//failure here will automatically
//log the user out as it should
}
});
}
Copied the answer from extjs forum
Option:2
If you want to open the file in new tab
/**
* open file in tab
*/
openReport: function () {
var url = 'downloadURL';
Ext.Ajax.request({
url: url,
method: 'GET',
autoAbort: false,
success: function(result) {
if(result.status == 204) {
Ext.Msg.alert('Empty Report', 'There is no data');
} else if(result.status == 200) {
var win = window.open('', '_blank');
win.location = url;
win.focus();
}
},
failure: function() {
//failure here will automatically
//log the user out as it should
}
});
}
You cannot use ajax to download file. I've implemented file downloading in extjs which is like ajax. see the blog ajaxlikefiledownload.
FileDownload.downloadFile = function(arguments) {
var url = arguments['url'];
var params = arguments['params'];
var successCallback = arguments['success'];
var failureCallback = arguments['failure'];
var body = Ext.getBody();
var frame = body.createChild({
tag:'iframe',
cls:'x-hidden',
id:'hiddenframe-frame',
name:'iframe'
});
var form = body.createChild({
tag:'form',
cls:'x-hidden',
id:'hiddenform-form',
action: url,
method: 'POST',
target:'iframe'
});
if (params) {
for (var paramName in params) {
form.createChild({
tag:'input',
cls:'x-hidden',
id:'hiddenform-'+paramName,
type: 'text',
text: params[paramName],
target:'iframe',
value: params[paramName],
name: paramName
});
}
}
form.dom.submit();
FileDownload.isFinished(successCallback,failureCallback);
};
FileDownload.isFinished = function(successCallback,failureCallback) {
//Check if file is started downloading
if (Ext.util.Cookies.get('fileDownload') && Ext.util.Cookies.get('fileDownload')=='true' ) {
//Remove cookie call success callback
Ext.util.Cookies.set('fileDownload', null, new Date("January 1, 1970"),application.contextPath+'/');
Ext.util.Cookies.clear('fileDownload',application.contextPath+'/');
successCallback();
return;
}
//Check for error / IF any error happens then frame will load with content
try {
if(Ext.getDom('hiddenframe-frame').contentDocument.body.innerHTML.length>0){
Ext.util.Cookies.set('fileDownload', null, new Date("January 1, 1970"),application.contextPath+'/');
Ext.util.Cookies.clear('fileDownload',application.contextPath+'/');
failureCallback();
//Cleanup
Ext.getDom('hiddenframe-frame').contentDocument.body.innerHTML = "";
return;
}
}
catch (e) {
console.log(e);
}
console.log('polling..');
// If we are here, it is not loaded. Set things up so we check the status again in 100 milliseconds
window.setTimeout('FileDownload.isFinished('+successCallback+','+failureCallback+')', 100);
};
Usage :
FileDownload.downloadFile({
url : url,
params : params,
success : function(){
//Success call back here
},
failure : function(){
//Failure callbak here
}
});
In the http response you need to add a cookie nammed fileDownload = true
I just had to ad to the success function of the ajax request:
window.open('urltothefile.ext')