Ajax file upload with the "Form Plugin" for jQuery
I am using jQuery, and I would like to upload files with Ajax. I have made some searches and found it is not possible.
However, there is one jQuery plugin, jQuery Form Plugin, which allows us to upload files through Ajax.
It works very well, but I have a special problem. Here is my code:
$('#question-form').submit(function() {
var serialAnswers = '';
// Create a query string given some fields
// Format of the query string : answers[0][fr_fr][0]=a1fr&answers[0][fr_fr][1]=2&answers[0][en_uk][0]=a1en&answers[0][en_uk][1]=6&...
$('#question-answers > div').each(function(idx, elt) {
$('div[lang]', $(elt)).each(function(idxLang, eltLang) {
var lang = $(this).attr('lang');
serialAnswers += 'answers[' + idx + '][' + lang + '][0]=' + $("[answerpart=display]", $(eltLang)).val();
serialAnswers += '&answers[' + idx + '][' + lang + '][1]=' + $("[answerpart=value]", $(eltLang)).val() + '&';
});
});
$(this).ajaxSubmit({
datatype: "html",
type: "POST",
data: serialAnswers,
url: $(this).attr("action"),
success: function(retour) {
$('#res-ajax').html(retour);
}
});
return false;
});
As you can see, I have to replace the $.ajax
call by a $(this).ajaxSubmit()
call, with the same options. Moreover, I have to create a query string (serialAnswers in the code) according to some fields in order to transmit it to the PHP code.
Here is what I开发者_StackOverflow used to do when I had no file to upload. I just serialized the form fields and added my query string named serialAnswers:
$.ajax({
datatype: "html",
type: "POST",
data: $(this).serialize() + '&' + serialAnswers,
url: $(this).attr("action")
success: function(retour) {
$("#res-ajax").html(retour);
}
});
But my problem is that the form plugin transmits my additional data (the query string) that way (in the PHP file):
Array
(
[question_heading_fr_fr] => something
[question_heading_en_uk] => nothing
[question_type] => 5
[0] => a
[1] => n
[2] => s
[3] => w
[4] => e
[5] => r
[6] => s
[7] => [
[8] => 0
[9] => ]
[10] => [
[11] => f
[12] => r
[13] => _
[14] => f
[15] => r
[16] => ]
....
)
According to the documentation, I have to pass a JSON object to the data option, like this:
data: { key1: 'value1', key2: 'value2' }
But I don't know how to convert my query string to a JSON object and if it would be interpreted as an array on the PHP side.
Is there a solution?
EDIT: Even if I use an iframe, I don't know how to add a query string with information which does not come from the form (my serialAnswer
from the code above).
Try Uploadify. This is a Flash based upload plugin. It is easy to implement and supports multiple file upload.
I'm not sure exactly what your looking for but why can't you just do:
data: {'key1':$(this).serialize(),'key2': serialAnswers}
Then on the PHP side to decode PHP you do
json_decode($arr); //Where $arr is whatever the array is that gets passed
If you need to pass back a JSON response you just do:
json_encode($arr); //Where arr is an array you build within your script
I'm assuming this is what you want.
EDIT: I found a new solution, and it works :)
I have modified the jQuery Form Plugin. Plugin page: http://jquery.malsup.com/form/#getting-started. Script: https://github.com/malsup/form/raw/master/jquery.form.js
In order to use this syntax:
$('#myform').submit(function() {
var queryString = 'answers[0][fr_fr][0]=a1fr&answers[0][fr_fr][1]=2&answers[0][en_uk][0]=a1en&answers[0][en_uk][1]=6';
$(this).ajaxSubmit({
dataType: 'html',
data: queryString
});
return false;
});
instead of:
$('#myform').submit(function() {
$(this).ajaxSubmit({
dataType: 'html',
data: {'key':'value' }
});
return false;
});
I have modified the plugin code.
Find this:
var n,v,a = this.formToArray(options.semantic);
if (options.data) {
options.extraData = options.data;
for (n in options.data) {
if(options.data[n] instanceof Array) {
for (var k in options.data[n]) {
a.push( { name: n, value: options.data[n][k] } );
}
}
else {
v = options.data[n];
v = $.isFunction(v) ? v() : v; // if value is fn, invoke it
a.push( { name: n, value: v } );
}
}
}
And delete all the if (options.data)
and its content. A few lines after these ones, find this:
var q = $.param(a);
And add this right after it:
if (options.data) {
options.extraData = options.data;
q += '&' + options.data;
}
In the function fileUpload(), find this:
var extraInputs = [];
try {
if (s.extraData) {
for (var n in s.extraData) {
extraInputs.push(
$('<input type="hidden" name="'+n+'" value="'+s.extraData[n]+'" />')
.appendTo(form)[0]);
}
}
// Add iframe to doc and submit the form
$io.appendTo('body');
io.attachEvent ? io.attachEvent('onload', cb) : io.addEventListener('load', cb, false);
form.submit();
}
And replace it by:
var extraInputs = [];
try {
if (s.extraData) {
var couples = s.extraData.split('&');
for (var c=0 ; c < couples.length ; c++)
{
var couple = couples[c].split('=');
extraInputs.push(
$('<input type="hidden" name="'+couple[0]+'" value="'+couple[1]+'" />')
.appendTo(form)[0]);
}
}
// add iframe to doc and submit the form
$io.appendTo('body');
io.attachEvent ? io.attachEvent('onload', cb) : io.addEventListener('load', cb, false);
form.submit();
}
You now can add a query string thanks to these modifications and uploading an image at the same time.
精彩评论