Загрузка Ajax-файла с «Плагином формы» для jQuery - PullRequest
5 голосов
/ 12 мая 2011

Я использую jQuery, и я хотел бы загружать файлы с помощью Ajax. Я сделал несколько поисков и обнаружил, что это невозможно.

Однако есть один плагин jQuery, Плагин jQuery Form , который позволяет загружать файлы через 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;
});

Как видите, я должен заменить вызов $.ajax на вызов $(this).ajaxSubmit() с теми же параметрами. Более того, мне нужно создать строку запроса (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.

Есть ли решение?

EDIT : Даже если я использую iframe, я не знаю, как добавить строку запроса с информацией, которая не приходит из формы (мой serialAnswer из кода выше).

Ответы [ 3 ]

0 голосов
/ 12 мая 2011

РЕДАКТИРОВАТЬ : Я нашел новое решение, и оно работает:)

Я изменил плагин jQuery Form. Страница плагина: 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;
}

В функции fileUpload () найдите это:

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

Теперь вы можете добавить строку запроса благодаря этим изменениям и одновременно загрузить изображение.

0 голосов
/ 13 мая 2011

Попробуйте Загрузить .Это плагин для загрузки Flash .Это легко реализовать и поддерживает загрузку нескольких файлов.

0 голосов
/ 12 мая 2011

Я не уверен, что именно вы ищете, но почему вы не можете просто сделать:

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

Я предполагаю, что это то, что вы хотите.

...