I'm submitting the form through ajax using jquery serialization function - javascript

var values = $('#form_field').serialize();
dataS = "val="+values;
$.ajax({
type: "POST",
url: URL,
data: dataS,
cache: false,
dataType: 'json',
success: function(response)
{ },
});
But the form has an (<input type="file"> field) how do I pass the file into the form using this ajax serialization method. When I print $_FILES doesn't getting any output.

You can't past the $_FILES variable when using ajax. I can assure you that. Thanks.

Ajax does not support file uploads, you should use iframe instead.
you can check further detail here

Posting via Ajax file upload isn't straight forward. First, it isn't directly doable using XHR1.
There are two main ways to do the uploads, using a frame and using the XHR2 spec and the FormData object. This is the method I would recommend.
The easiest way to do this is then to perform two uploads. I'm going to borrow some code here, from GitHub user optikalefx to show you how to do it using jQuery:
// Ajax File upload with jQuery and XHR2
// Sean Clark http://square-bracket.com
// xhr2 file upload
// data is optional
$.fn.upload = function(remote,data,successFn,progressFn) {
// if we dont have post data, move it along
if(typeof data != "object") {
progressFn = successFn;
successFn = data;
}
return this.each(function() {
if($(this)[0].files[0]) {
var formData = new FormData();
formData.append($(this).attr("name"), $(this)[0].files[0]);
// if we have post data too
if(typeof data == "object") {
for(var i in data) {
formData.append(i,data[i]);
}
}
// do the ajax request
$.ajax({
url: remote,
type: 'POST',
xhr: function() {
myXhr = $.ajaxSettings.xhr();
if(myXhr.upload && progressFn){
myXhr.upload.addEventListener('progress',function(prog) {
var value = ~~((prog.loaded / prog.total) * 100);
// if we passed a progress function
if(progressFn && typeof progressFn == "function") {
progressFn(prog,value);
// if we passed a progress element
} else if (progressFn) {
$(progressFn).val(value);
}
}, false);
}
return myXhr;
},
data: formData,
dataType: "json",
cache: false,
contentType: false,
processData: false,
complete : function(res) {
var json;
try {
json = JSON.parse(res.responseText);
} catch(e) {
json = res.responseText;
}
if(successFn) successFn(json);
}
});
}
});
};
I should also note that browser support for this is a little more limited, despite XHR2 being around for 2 years now: https://developer.mozilla.org/en-US/docs/Web/API/FormData contains more information as well as a Browser compatibility chart.

Related

How to add custom properties to file form javascript / jquery

I'm aiming to send fileform with images and additional information like height and width. I can't figure out how to add some custom props to file form object.
$("#saveImg").on('click', function () {
var formData = new FormData(),
allFiles = [];
$('input[name=fileUpload]').each(function (index) {
if (inputFileValidation(this)) {
(function (files) {
if (files.length != 0) { allFiles.push(files[0]); }
})(this.files)
}
});
for (var i = 0; i != allFiles.length; i++) {
var img = new Image()
img.src = window.URL.createObjectURL(allFiles[i]);
$(img).on('load', function () {
formData.append("files_h", img.naturalHeight);
formData.append("files_w", img.naturalWidth);
formData.append("files", allFiles[i]);
window.URL.revokeObjectURL(allFiles[i]);
});
}
$.ajax({
url: '#Url.Action("Upload", "Image")',
data: formData,
processData: false,
contentType: false,
type: "POST",
success: function () {}
errors: function () {}
});
});
[HttpPost]
public async Task<IActionResult> Upload (IList<IFormFile> files)
{
//do something ;
}
I also tried:
[HttpPost]
public async Task<IActionResult> Upload (IList<IFormFile> files, IList<IFormFile> files_h, IList<IFormFile> files_w)
{
//do something ;
}
Maybe you have another idea how to send image with additional data? I tried to convert file form and additional info to JSON by that didn't work.
Edit
Thank you all for your suggestion, they are really important to me because I will definitely use them in the future.
However, in this project I have already given up using the file reader due to its asynchrony and having fun with promise. The aim is simple and less javascript and more c#
I apologize for misleading you in the title javascript andjquery - and I mark the answer related to c #. I did this because this answer is related to my next task because the CoreCompat.System.Drawing library is undoubtedly still useful for editing photos in the future.
Thanks!!
If you want to get the Width and Height properties while uploading images in ASP.NET Core. I suggest you to install this package: CoreCompat.System.Drawing
Install-Package CoreCompat.System.Drawing -Version 1.0.0-beta006
In the server, after saving your files to the specific path. You could use System.Drawing.Image class to get the Width and Height properties:
using (var image = System.Drawing.Image.FromFile(filePath))
{
int width = image.Width;
int height = image.Height;
}
You don't have to add files_h and files_w properties to your client model before sending to server.
And then, by using this way, I've edited your js code to:
$("#saveImg").on('click', function () {
var formData = new FormData();
for (var input of Array.from($('input[name=fileUpload]')))
{
if (inputFileValidation(input) && input.files.length) {
formData.append('files', input.files[0]);
}
}
$.ajax({
url: '#Url.Action("Upload", "Image")',
data: formData,
processData: false,
contentType: false,
type: "POST",
success: function () {}
errors: function () {}
});
});
This is one approach; taken from there:
$('#btnUpload').click(function () {
// Checking whether FormData is available in browser
if (window.FormData !== undefined) {
var fileUpload = $("#FileUpload1").get(0);
var files = fileUpload.files;
// Create FormData object
var fileData = new FormData();
// Looping over all files and add it to FormData object
for (var i = 0; i < files.length; i++) {
fileData.append(files[i].name, files[i]);
}
// Adding one more key to FormData object
fileData.append('username', ‘Manas’);
$.ajax({
url: '/Home/UploadFiles',
type: "POST",
contentType: false, // Not to set any content header
processData: false, // Not to process data
data: fileData,
success: function (result) {
alert(result);
},
error: function (err) {
alert(err.statusText);
}
});
} else {
alert("FormData is not supported.");
}
});
Another approach is to use the FileReader class to read the uploaded file, convert it to a base 64 string. Then you can send the base 64 string to the server.

Error by using formData

I tried to do this for working with a part of values from a html-form.
var formData = new FormData();
formData.append('file', $('#FORM_ADD_LANG_FILE')[0].files[0]);
formData.append('add_lang_code', $('#FORM_ADD_LANG_CODE').val());
formData.append('job', jobid);
var post_setting = new Array(false,false);
But in my console it is showing the following error and I don't know why it is
"TypeError: 'append' called on an object that does not implement interface FormData."
I generate the ajax-call by this function
function getAJAXcall(processData, contentType, formData, callback) {
var returnValue = {
url: '".$global['serverurl']."module/".$m['ID']."/code/cms_data.php',
type: 'POST',
data: formData,
success: callback
};
if (processData === **false**) returnValue.processData = processData;
if (contentType === **false**) returnValue.contentType = contentType;
}
And call them up in this way
$.ajax(getAJAXcall(post_setting[0], post_setting[1], formData, function(result)
{ ...my callback functions... }
Also i try to change the post_setting = new Array(false,false); to true, true but the result was the same
You use the right method call for this, so presumably there's something else wrong.
Could FormData be overwritten by some other library (perhaps a polyfill), that knows nothing of .append()? Check the console of your browser for FormData and see, if you can spot anything fishy there.
You use the result in a jQuery AJAX call, true? Then this answer applies to you. In a nutshell, add
processData: false,
to your AJAX parameters.

TypeError: Illegal invocationType when passing file through ajax

My goal is to pass a file to my backend which runs on laravel. The file is drag and dropped on the web page and not my input file. I went through the previous issues on stack overflow and fixed my code accordingly but still the issue exists.
Here is my javascript code that uses ajax to pass the file
$("html").on("drop", function (e) {
e.preventDefault();
e.stopPropagation();
var dt = e.dataTransfer || (e.originalEvent && e.originalEvent.dataTransfer);
var files = e.target.files || (dt && dt.files);
if (files) {
for (var i = 0; i < e.originalEvent.dataTransfer.files.length; i++) {
var file_ext = e.originalEvent.dataTransfer.files[i].name.split('.').pop();
console.log(file_ext);
if ((file_ext == 'pdf') || (file_ext == 'docx') || (file_ext == 'txt')) {
console.log('right file');
var resume = e.originalEvent.dataTransfer.files[i].value;
var form_data = new FormData();
form_data.append("resume", resume);
var resume_val = e.originalEvent.dataTransfer.files[i].name;
console.log(form_data);
var token = $('#token').val()
var hello = "hello";
$.ajax({
url: '/resume_upload',
type: 'POST',
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
},
data: ({
resume: form_data,
wish: "Naveen its working"
}),
success: function (data) {
console.log(data.msg);
alert(data.msg);
},
error: function (xhr, status, error) {
console.log(error);
alert(error)
}
});
} else {
console.log('wrong file');
}
}
} else {
console.log('file not recieved');
}
});
Here is where i get the file
var resume = e.originalEvent.dataTransfer.files[i].value;
var form_data = new FormData();
form_data.append("resume",resume);
But when i console.log(form_data) it logged FormData{} just empty form data. So obviously i pass nothing with my ajax function. Am i doing anything wrong in getting the file ? I don't have an idea how to go about this.
Maybe I misunderstood what do you want but I think you should do stg like this:
var form_data = new FormData();
form_data.append('resume_file_name', e.originalEvent.dataTransfer.files[i].value);
form_data.append('resume_file', e.originalEvent.dataTransfer.files[i]);
form_data.append('wish', "Naveen its working");
if u want to upload the file, not just some file info
and with FormData, you can pass all the data you want, so just pass this to $.ajax data parameter:
data: form_data,
and there is something else, may this was the original problem:
when jQuery handles the parameters it also tries to convert it, but this causes problems, when pass a FormData type to data attribute, so you should also add these parameters to the $.ajax input object:
processData: false,
contentType: false
parameters.
Sorry for my bad english!

How to submit a form and pass some extra parameters to a $.getJSON callback method?

I know how to pass some parameters to a JQuery $.getJSON callback method, thanks to this question:
$.getJSON('/website/json',
{
action: "read",
record: "1"
},
function(data) {
// do something
});
And I can also submit a form to a $.getJSON callback method:
$.getJSON('/website/json', $(formName)
function(data) {
// do something
});
But I want to pass some parameters AND submit some form elements. How can I combine the two things togheter?
I could serialize the form elements and manually add some parameters to the url, and it looks like it works:
$.getJSON('/website/json',
'action=read&record=1&'
+ $(formName).serialize(),
function(data) {
// do something
});
But it doesn't look very elegant. Is this the proper way, or there's a better way to do it?
We could implement the functionality demonstrated in this answer as a custom jQuery instance method which produces an object of key/value pairs from a form and combines it with the properties that aren't derived from the form:
$.fn.formObject = function (obj) {
obj = obj || {};
$.each(this.serializeArray(), function (_, kv) {
obj[kv.name] = kv.value;
});
return obj;
};
$.getJSON('/website/json', $(formName).formObject({
action: "read",
record: "1"
}), function(data) {
// do something
});
Make an Ajax post to send the data to the server. Retrieve the parameter data in the backend code along with the form data.
var formData = {data from form};
formData.action = 'read';
formData.post = '1';
$.ajax({
url: '/website/json',
type: "post",
data: formData
}).done(function (data) {
// remove prior values set upon request response
formData.action = null;
formData.post = null;
});

Display search results from API

Hello there I'm trying to create an app to search for recipes. I've tried using the Yummly API and BigOven api, but I can't get either to work.
here is the code i have for bigOven. I can't get any search results to appear in the "results".
$(function() {
$('#searchform').submit(function() {
var searchterms = $("#searchterms").val();
// call our search twitter function
getResultsFromYouTube(searchterms);
return false;
});
});
function getResultsFromYouTube (searchterms) {
var apiKey = "dvxveCJB1QugC806d29k1cE6x23Nt64O";
var titleKeyword = "lasagna";
var url = "http://api.bigoven.com/recipes?pg=1&rpp=25&title_kw="+ searchterms + "&api_key="+apiKey;
$.ajax({
type: "GET",
dataType: 'json',
cache: false,
url: url,
success: function (data) {
alert('success');
console.log(data);
$("#results").html(data);
}
});
}
Can anyone give me instructions on how to do this?? Thank you very much.
The API is returning JSON data, not HTML. I checked the API docs, and JSONP isn't necessary.
However, when you run this code:
$('#results').html(data);
Your code is going to just put the JSON into your HTML, and that isn't going to get displayed properly. You didn't say whether console.log(data) outputs the data correctly, but I'll assume it is.
So, you'll need to transform your JSON into HTML. You can do that programmatically, or you can use a templating language. There are a number of options, including underscore, jquery, mustache and handlebars.
I recommend handlebars, but it's not a straightforward bit of code to add (the main difficulty will be loading your template, or including it in your build).
http://handlebarsjs.com/
It would depend on you which key and values you have to show to your user's and in which manner... For ex. there is even an image link, you could either show that image to your user's or could just show them the image link...
Simple <p> structure of all the key's with there value's
jQuery
$.each(data.Results, function (key, value) {
$.each(value, function (key, value) {
$("#result").append('<p>Key:-' + key + ' Value:-' + value + '</p>');
});
$("#result").append('<hr/>');
});
Your ajax is working, you just need to parse the results. To get you started:
$.ajax({
type: "GET",
dataType: 'json',
cache: false,
url: url,
success: function (data) {
// Parse the data:
var resultsString = "";
for (var i in data.Results){
console.log( data.Results[i] );
resultsString+= "<div>"+data.Results[i].Title+ " ("+data.Results[i].Cuisine+")</div>";
}
$("#results").html(resultsString);
// If you want to see the raw JSON displayed on the webpage, use this instead:
//$("#results").html( JSON.stringify(data) );
}
});
I had created a little recursive function that iterates through JSON and spits out all of the values (I subbed my output for yours in the else condition) -
function propertyTest(currentObject, key) {
for (var property in currentObject) {
if (typeof currentObject[property] === "object") {
propertyTest(currentObject[property], property);
} else {
$('#results').append(property + ' -- ' + currentObject[property] + '<br />');
}
}
}
Then I called it within your AJAX success -
$.ajax({
type: "GET",
dataType: 'json',
cache: false,
url: url,
success: function (data) {
console.log(data);
propertyTest(data); // called the function
}
});
It spits out all of the data in the JSON as seen here - http://jsfiddle.net/jayblanchard/2E9jb/3/

Categories

Resources