AJAX Fileupload with jquery - javascript

I am currently trying to solve a problem.
I have several forms on a single page which get sent to the backend asynchronously via ajax.
Now some of them need to have a fileupload which doesnt break the process, so it alsoneeds to be handled asynchronously.
I am trying to figure it out like that :
// Allgemein Submit
$allgSubmit.click(function(){
event.preventDefault();
var gehrKundennummer = $('#gehrKundennummer').val();
var kundenklasse = $("input[type='radio'][name='kundenklasse']:checked").val();
var lkw12t = $('#lkw12t').val();
var lkw3t = $('#lkw3t').val();
var autobus = $('#autobus').val();
var firmenname1 = $('#firmenname1').val();
var firmenname2 = $('#firmenname2').val();
var uidnummer = $('#uidnummer').val();
var peselregon = $('#peselregon').val();
var firmenart = $('#firmenart option:selected').val();
var strasse = $('#strasse').val();
var ort = $('#ort').val();
var plz = $('#plz').val();
var land = $('#land').val();
var fd = new FormData();
var file = fd.append('file', $('#allg_firmen_dok').get(0).files[0]);
var allgArray = {
'gehrKundennummer':gehrKundennummer,
'kundenklasse':kundenklasse,
'lkw12t':lkw12t,
'lkw3t':lkw3t,
'autobus':autobus,
'firmenname1':firmenname1,
'firmenname2':firmenname2,
'uidnummer':uidnummer,
'peselregon':peselregon,
'firmenart':firmenart,
'strasse':strasse,
'ort':ort,
'plz':plz,
'land':land,
'file':file
};
//var data = new FormData();
//jQuery.each(jQuery('#allg_firmen_dok')[0].files, function(i, file) {
// data.append('file-'+i, file);
//});
console.log(allgArray);
$.ajax({
url: "PATHTOFILE/logic/logic_update_client_allg.php",
type: "POST",
data: allgArray,
processData: false, // tell jQuery not to process the data
contentType: false,
success: function(allgArray){
alert(allgArray);
var allgSave = $('#allgSave');
allgSave.text('Aktualisieren erfolgreich!');
allgSave.toggle();
},
error: function(){
var allgSave = $('#allgSave');
allgSave.text('Aktualisieren fehlgeschlagen!');
allgSave.toggle();
}
});
});
The console log of the array returns all values correctly except the one for "file"
it says undefined.
I don't know how to deal with it, are there any requirements that im missing?
Thanks for any kind of help
EDIT
var file = fd.append('file', $('#allg_firmen_dok').get(0).files[0]);
returns undefined

I think the variable fd = new FormData() is an Object and it has attribute "file". So it cannot pass the attribute "file" to another Object "allgArray"
You need to check about it before you call function
$.ajax({
url: "PATHTOFILE/logic/logic_update_client_allg.php",
type: "POST",
data: allgArray,
Think about the data you send! It maybe another instance to get data from "file" of "fd". Hope it help you! ^^
Btw, I used AJAX to send file last time
$(document).ready(function (e) {
$("#Form").on('submit',(function(e) {
e.preventDefault();
$.ajax({
url: "uploader.php", // Url to which the request is send
type: "POST", // Type of request to be send, called as method
data: new FormData(this), // Data sent to server, a set of key/value pairs (i.e. form fields and values)
contentType: false, // The content type used when sending data to the server.
cache: false, // To unable request pages to be cached
processData:false, // To send DOMDocument or non processed data file it is set to false
success: function(data) // A function to be called if request succeeds
{
console.log(data);
}
});
}));
});

add headers: { "Content-Type": "multipart/form-data" } in ajax option

Related

Get Object XmlDocument value

I'm executing an ajax call to a external api (this cannot be modified) to upload an store a file into a folder. This request must return a path (ex. "C:\Doctos\File.pdf" but after a console.log is returning something like this:
#document < string xmlns="http://tempuri.org/">"C:\Doctos\File.pdf"
So my question is, what can I do to get only the text that I want without any change in the api (because I'm not able to do it).
Here is the ajax call that I'm using.
PD. This ajax call is using the provided structure for the dev team that developed the api so things like dataType also cannot be modified
var data = new FormData();
var files = $('#fileUpload').get(0).files;
if (files.length > 0) {
data.append("UploadedFile", files[0]);
}
$.ajax({
type: 'POST',
url: 'api/v1/moreurl/UploadFile',
contentType: false,
processData: false,
data: data,
success: function (data) {
var res = data;
//Returns above example
console.log(res);
//Returns something like <p>[object XMLDocument]</p>
$('#MyInput').attr('src', res);
}
});
I would use regular expressions to get the desired string from received data. Put this after success line.
var regex = />\"(.*)\"/;
var matched = regex.exec(data);
var result = matched[1];
console.log(result);
The regex matches the last quoted string in your example.
You can get the data in the xml with jQuery
$.ajax({
type: 'POST',
url: 'api/v1/moreurl/UploadFile',
contentType: false,
processData: false,
data: data,
success: function (data) {
// Get the contents of the xml
var file = $(data).find('string').text();
$('#MyInput').attr('src', file);
}
});

How to receive a data from the JSon method?

I have a method in my controller that submits some changes in the database after receiving a filename that being uploaded to the server. Also this method is getting the fileNameOrigin and fileNameUnique (to be downloaded for saving in the server folder)
public JsonResult Upload()
{
var upload = Request.Files[file];
string fileNameOrigin = System.IO.Path.GetFileName(upload.FileName);
string fileNameUnique = String.Format("{0}_" + fileNameOrigin,
DateTime.Now.ToString("yyyyMMddHHmmss"));
//there is more code that isn't needed in my case
return Json(fileNameOrigin, fileNameUnique);
}
So, here's the question - how to send and receive this data on the client side?
$('#uploadFile').on('change', function (e) {
e.preventDefault();
var files = document.getElementById('uploadFile').files;
if (files.length > 0) {
if (window.FormData !== undefined) {
var data = new FormData();
for (var x = 0; x < files.length; x++) {
data.append("file" + x, files[x]);
}
$.ajax({
type: "POST",
url: '#Url.Action("Upload", "ChatRooms")',
contentType: false,
processData: false,
data: data,
success: onSuccess, //here I need to receive data and do smth with it
error: onError
});
}
}
});
Create a anonymous object with the properties that are required and then pass that single object to the JSON method like:
var data = new {
FileNameOrigin = fileNameOrigin,
FileNameUnique = fileNameUnique
};
return Json(data);
In success callback of ajax, you can access it, for just to check it is working log it on console to see what server has returned like:
success: function(data) {
console.log(data);
},
you might also need to specify datatype in ajax call to json which dictates that JSON is expected from server to be returned in response to this ajax call:
dataType: "json"
Hope it helps!

looping through fileList with javascript

What I am attempting to accomplish here is to create a separate ajax request for each file being uploaded. I have an ajax call that creates a record and returns some html and the tempID of a record that is used by an ajax call which executes on success of the first call. This process appears to be functioning correctly. Where the problem is arising is the loop through the filesList. Before the ajax calls the loop appears to be working fine, but during the ajax call when I'm expecting the files list to increment to the next file in the array it is sending the first file again.
If I only select a single file then everything works correctly. It is as if the ajax calls do not see that the variable "file" is being reset at the beginning of the loop when there are multiple files....got me stumped...
/* Fire the ajax requests when the input files array changes
--------------------------------------------------------------------------*/
$('#theFile').on('change', function()
{
var len = this.files.length;
for(var i = 0; i < len; i++)
{
var file = this.files[i];
// console.log(file.name); This shows the correct file name
var formData = new FormData();
formData.append("file_" + i, file);
$.ajax(
{
url: '/controllerName/buildImageLoadingDIVS',
type: 'POST',
dataType:'json',
data: 'fileName=' + file.name,
success: function(data1)
{
$('#theImages').append(data1.content);
formData.append("tempID", data1.tempID);
// console.log(file.name);
// This shows the first filename in the array as if
// variable "file" was never set to new filelist
$.ajax(
{
url: '/controllerName/the_image_upload',
type: 'POST',
data: formData,
processData: false,
contentType: false,
success: function(data2)
{
$('#temp_wrapper_' + data1.tempID).html(data2);
}
});
}
});
}
You are facing closure problem. As all the success callback are sharing the same closure, so if any success callback is getting executed after the loop ends (which will be in most of the cases) all the success callback is sharing the same file value. Solution of this is creating a closure with IIFE.
Here is the modified code :
//dummy file array
var fileArray = ['file1', 'file2', 'file3']
var len = fileArray.length;
for(var i = 0; i < len; i++)
{
var file = fileArray[i];
console.log(file);
var formData = new FormData();
formData.append("file_" + i, file);
(function(params){
var file = params.file;
var formData = params.formData;
$.ajax(
{
//used this url for testing purpose, replace it with yours
url: 'http://fiddle.jshell.net',
type: 'get',
//change the datatype in your implementation
dataType:'html',
data: 'fileName=' + file,
success: function(data1)
{
//$('#theImages').append(data1.content);
formData.append("tempID", data1.tempID);
console.log("file name in success " + file);
$.ajax(
{
url: 'http://fiddle.jshell.net',
type: 'get',
data: formData,
processData: false,
contentType: false,
success: function(data2)
{
console.log("success");
}
});
},
error : function(){
console.log("error");
}
});
})({
'formData' : formData,
'file' : file
});
}
You can find the fiddle here

Add data to Jquery.Ajax post when uploading file?

I'm building a drag n drop upload feature for my MVC 4 webapp using this tutorial:
http://hayageek.com/drag-and-drop-file-upload-jquery/
However, besides the file, I also want to send info regarding where it came from (some ID for instance) and the type (domain-type).
In my ajax post below, how can I add extra data and read it server side?
In the tutorial code a line with 'extra data' is seen, however it is not actually implemented.
function sendFileToServer(formData, status) {
var uploadURL = '/home/upload';
var extraData = {}; //Extra Data.
var jqXHR = $.ajax({
xhr: function() {
var xhrobj = $.ajaxSettings.xhr();
if (xhrobj.upload) {
xhrobj.upload.addEventListener('progress', function(event) {
var percent = 0;
var position = event.loaded || event.position;
var total = event.total;
if (event.lengthComputable) {
percent = Math.ceil(position / total * 100);
}
//Set progress
status.setProgress(percent);
}, false);
}
return xhrobj;
},
url: uploadURL,
type: "POST",
contentType: false,
processData: false,
cache: false,
data: formData,
success: function (data) {
status.setProgress(100);
//$("#status1").append("File upload Done<br>");
}
});
status.setAbort(jqXHR);
}
Thanks!
To pass additional data to your controller via Ajax Upload File, it just needs to append your additional data to formData in your Ajax call function(sendFileToServer). i.e. you'd like to pass an upload target folder:
formData.append('targetFolder', 'User File Upload Folder');
and in your action get access to your additional parameter:
[HttpPost]
public ActionResult Upload(HttpPostedFileBase file, string targetFolder)
I fixed the problem by creating a workaround, I'm passing the extra data (id etc) via the URL which I receive as parameters on the controller method.

How to convert simple form submit to ajax call;

I have a form with input field which can be accessed like
var algorithm = document.forms["algoForm"]["algorithm"].value;
var input = document.forms["algoForm"]["input"].value;
and earlier call was
document.forms["algoForm"].submit();
and form was
<form name="algoForm" method="post" action="run.do">
It all run fine
Now I wanted convert it to the ajax call so that I can use the returned data from java code on the same page. So I used soemthing like
var algorithm = document.forms["algoForm"]["algorithm"].value;
var input = document.forms["algoForm"]["input"].value;
var data = 'algorithm = ' + algorithm + '&input = ' + input;
$.ajax(
{
url: "run.do",
type: "POST",
data: data,
success: onSuccess(tableData)
{ //line 75
alert(tableData);
}
}
);
However the above code doesn't run. Please help me make it run
Let's use jQuery's serialize to get the data out of the form and then use the jQuery's ajax function to send the data to the server:
var data = $("form[name=algoForm]").serialize();
$.ajax({
url: "run.do",
type: "POST",
data: data,
success: function(tableData){
alert(tableData);
}
});
data expects a literal object, so you need:
var data = {
'algorithm': algorithm,
'input': input
};
Instead of retrieving all the parameter value and then sending them separately (which can be done server side as well, using below code), Use this:
var $form = $("#divId").closest('form');
data = $form.serializeArray();
jqxhr = $.post("SERVLET_URL', data )
.success(function() {
if(jqxhr.responseText != ""){
//on response
}
});
}
divId is id of the div containing this form.
This code will send all the form parameters to your servlet. Now you can use request.getParameter in your servlet to get all the individual fields value on your servlet.
You can easily convert above jquery post to jquery ajax.
Hope this helps :)
// patching FORM - the style of data handling on server can remain untouched
$("#my-form").on("submit", function(evt) {
var data = {};
var $form = $(evt.target);
var arr = $form.serializeArray(); // an array of all form items
for (var i=0; i<arr.length; i++) { // transforming the array to object
data[arr[i].name] = arr[i].value;
}
data.return_type = "json"; // optional identifier - you can handle it on server and respond with JSON instead of HTML output
$.ajax({
url: $form.attr('action') || document.URL, // server script from form action attribute or document URL (if action is empty or not specified)
type: $form.attr('method') || 'get', // method by form method or GET if not specified
dataType: 'json', // we expect JSON in response
data: data // object with all form items
}).done(function(respond) {
console.log("data handled on server - response:", respond);
// your code (after saving)
}).fail(function(){
alert("Server connection failed!");
});
return false; // suppress default submit action
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
I don't know how but this one runs well,
var algorithm = document.forms["algoForm"]["algorithm"].value;
var input = document.forms["algoForm"]["input"].value;
$.post('run.do', {
algorithm : algorithm,
input : input
}, function(data) {
alert(data);
}
);

Categories