使用jQuery的“表单插件”来上传Ajax文件

使用jQuery的“表单插件”来上传Ajax文件

问题描述:

我正在使用jQuery,并且想用Ajax上传文件。我做了一些搜索,发现它是不可能的。使用jQuery的“表单插件”来上传Ajax文件

但是,有一个jQuery插件jQuery Form Plugin,它允许我们通过Ajax上传文件。

它工作得很好,但我有一个特殊的问题。这里是我的代码:

$('#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; 
}); 

正如你所看到的,我有一个$(this).ajaxSubmit()调用替换$.ajax调用,使用相同的选项。此外,我必须根据一些字段创建一个查询字符串(代码中的serialAnswers),以便将其传输到PHP代码。

这是当我没有文件上传时我曾经做过的事情。我只是序列化的表单字段,并添加我的命名serialAnswers查询字符串:

$.ajax({ 
    datatype: "html", 
    type: "POST", 
    data: $(this).serialize() + '&' + serialAnswers, 
    url: $(this).attr("action") 
    success: function(retour) { 
     $("#res-ajax").html(retour); 
    } 
}); 

但我的问题是,表单插件发送我的附加数据(查询字符串)这种方式(在PHP文件):

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] => ] 
    .... 
) 

根据该文件,我有一个JSON对象传递给数据选项,如:

data: { key1: 'value1', key2: 'value2' } 

但我不知道该如何处理我的查询字符串转换成JSONØ对象,如果它将被解释为PHP端的数组。

有没有解决方案?

编辑:即使我使用iframe,我不知道如何添加与信息的查询字符串,它并非来自表单(我serialAnswer从上面的代码)。

+0

[Uploadify](http://www.uploadify.com/)? – ifaour 2011-05-11 20:24:58

+1

如果可能,我不想使用闪存 – 2011-05-11 20:58:02

编辑:我发现了一个新的解决方案,它的工作:)

我已经修改了jQuery表单插件。插件页面:http://jquery.malsup.com/form/#getting-started。脚本:https://github.com/malsup/form/raw/master/jquery.form.js

为了使用这个语法:

$('#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; 
}); 

代替:

$('#myform').submit(function() { 
    $(this).ajaxSubmit({ 
     dataType: 'html', 
     data: {'key':'value' } 
    }); 

    return false; 
}); 

我已经修改了插件代码。

找到这个:

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 }); 
     } 
    } 
} 

,并删除所有if (options.data)及其内容。这些的后几行,找到这个:

var q = $.param(a); 

,并在其后添加此权:

if (options.data) { 
    options.extraData = options.data; 
    q += '&' + options.data; 
} 

在功能文件上传(),发现这个:

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(); 
} 

而更换它通过:

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(); 
} 

你现在可以添加一个查询字符串感谢这些修改和上传图像在同一时间。

我不知道你寻找什么,但为什么你不能只是做:

data: {'key1':$(this).serialize(),'key2': serialAnswers} 

然后在PHP端你做解码PHP

json_decode($arr); //Where $arr is whatever the array is that gets passed 

如果您需要回传一个你刚刚做的JSON响应:

json_encode($arr); //Where arr is an array you build within your script 

我假设这就是你想要的。

+0

serialAnswers是查询字符串。当这个数据被传送到PHP时,它被转换成数组,所以我得到:[key2] => [0] [fr_fr] [0] =某事&答案[0] [fr_fr] [1] = 2&答案[ 0] [en_uk] [0] =其他&...' 所以我不能解码它与json_decode – 2011-05-11 20:57:00

+0

嗯这是一个很好的你在这里得到了自己。我现在没有任何东西,但我会睡上去,回到你身边:) – jefffan24 2011-05-12 00:24:55

尝试Uploadify。这是基于Flash的上传插件。它很容易实现并支持多个文件上传。

+0

正如我告诉@ifaour,我一直在寻找一种非闪存解决方案。 我已经回答了我的问题,看看这个话题;) – 2011-05-13 15:36:38