JQuery: 'Uncaught TypeError: Illegal invocation' na solicitação ajax - vários elementos

112

Eu tenho dois elementos selecionados, A e B: quando a opção selecionada de A muda, as opções de B devem ser atualizadas de acordo. Cada elemento em A implica muitos elementos em B, é uma relação um-para-muitos (A contém nações, B deve conter cidades localizadas em uma determinada nação).

A função do_ajaxdeve executar a solicitação assíncrona:

function do_ajax(elem, mydata, filename)
{
    $.ajax({
        url: filename,
        context: elem,
        data: mydata,
        datatype: "html",
        success: function (data, textStatus, xhr) {
            elem.innerHTML = data;
        }
    });
}

Para atualizar as opções de B, adicionei uma chamada de função no onChangeevento de A. Esta é a função que é executada quando o evento onChange (de A) é acionado:

function my_onchange(e) // "e" is element "A"
{
    var sel_B = ... ; // get select element "B"

    // I skipped some code here
    // ...

    var data = {
        'mode': 'filter_city',
        'id_A': e[e.selectedIndex]
    };
    do_ajax(city_sel, data, 'ajax_handler.php');
}

}

Eu li em documentos JQuery que datapodem ser uma matriz (pares de valores-chave). Recebo o erro se colocar:

var data = {
        'mode': 'filter_city',
        'id_A': e[e.selectedIndex]
};

Em vez disso, não recebo esse erro se meus dados forem uma string:

var data = 'mode=filter_city&id_A=' + e[e.selectedIndex];

Mas eu preciso da "versão do array" da variável, no meu código php do lado do servidor.

O Uncaught TypeError: Illegal invocationestá localizado no arquivo "jquery-1.7.2.min.js", que está todo compactado, então não consegui descobrir que parte do código gerou o erro.

Existe alguma configuração que eu possa alterar em meu código para que ele aceite dados como uma matriz associativa?

Nadir Sampaoli
fonte

Respostas:

151

Graças à conversa com Sarfraz , pudemos descobrir a solução.

O problema era que eu estava passando um elemento HTML em vez de seu valor, que é realmente o que eu queria fazer (na verdade, no meu código php, preciso desse valor como uma chave estrangeira para consultar minha citiestabela e filtrar as entradas corretas).

Então, em vez de:

var data = {
        'mode': 'filter_city',
        'id_A': e[e.selectedIndex]
};

deveria ser:

var data = {
        'mode': 'filter_city',
        'id_A': e[e.selectedIndex].value
};

Nota: verifique a resposta de Jason Kulatunga , ela cita o documento JQuery para explicar por que a passagem de um elemento HTML estava causando problemas.

Nadir Sampaoli
fonte
exatamente o que eu estava fazendo. Esqueci de usar .val ()
Usman Shaukat
Eu estava passando a opção de selecionar um elemento html em uma variável. Não percebi que não era texto simples, mas html.
Sterling Diaz
46

Dos documentos jQuery para processData:

processData Boolean
Padrão: true
Por padrão, os dados passados ​​para a opção de dados como um objeto (tecnicamente, qualquer coisa diferente de uma string) serão processados ​​e transformados em uma string de consulta, ajustando-se ao tipo de conteúdo padrão "application / x-www -form-urlencoded ". Se você deseja enviar um DOMDocument ou outros dados não processados, defina esta opção como false.

Fonte: http://api.jquery.com/jquery.ajax

Parece que você terá que usar processDatapara enviar seus dados para o servidor ou modificar seu script php para suportar parâmetros codificados de querystring.

Jason Kulatunga
fonte
1
Isso é verdade. Se eu pudesse ter visto antes, ele teria me indicado o erro real em meu código. Obrigado, acrescentarei uma observação em minha resposta.
Nadir Sampaoli
25

Eu estava recebendo este erro ao postar um objeto FormData porque não estava configurando a chamada ajax corretamente. A configuração abaixo corrigiu meu problema.

var myformData = new FormData();        
myformData.append('leadid', $("#leadid").val());
myformData.append('date', $(this).val());
myformData.append('time', $(e.target).prev().val());

$.ajax({
    method: 'post',
    processData: false,
    contentType: false,
    cache: false,
    data: myformData,
    enctype: 'multipart/form-data',
    url: 'include/ajax.php',
    success: function (response) {
        $("#subform").html(response).delay(4000).hide(1); 
    }
});
Mike Volmar
fonte
obrigado cara. u salvou meu dia e meu problema foi resolvido com a adição de "processData: false, contentType: false, cache: false," em meu corpo ajax. Muito obrigado.
CumaTekin
11

Eu li em documentos JQuery que os dados podem ser uma matriz (pares de valores-chave). Recebo o erro se colocar:

Este é um objeto, não uma matriz:

var data = {
        'mode': 'filter_city',
        'id_A': e[e.selectedIndex]
};

Você provavelmente quer:

var data = [{
        'mode': 'filter_city',
        'id_A': e[e.selectedIndex]
}];
Sarfraz
fonte
1
ele não lança mais aquele erro, mas parece que esses dados não estão sendo passados ​​para o meu $_GETarray do lado do servidor ( var_export($_GET)saídas array ( 'undefined' => 'undefined', ))
Nadir Sampaoli
@nadirs: Tente definir o tipo de método em seu $.ajaxmanipulador:type:'get',
Sarfraz
@Sarfraz o resultado é o mesmo. Do lado do servidor, as datachaves devem ser encontradas no array GET, certo? Ou talvez eles sejam enviados por outro método de solicitação de qualquer maneira?
Nadir Sampaoli
@nadirs: Algo assim funciona data: {foo:'myfoo', bar:'mybar'}, pode haver algum outro problema, eu acho.
Sarfraz
@Sarfraz sou um idiota, estava enviando um objeto HTML e[e.selectedIndex]enquanto deveria ter passado seu valor e[e.selectedIndex].value. Depois de corrigir essa falha, a notação de objeto funciona bem.
Nadir Sampaoli
7

Tive o mesmo problema recentemente, resolvido ao adicionar traditional: true,

deco
fonte
Isso realmente funciona, suponho que apenas para navegadores modernos
barnacle.m
0
function do_ajax(elem, mydata, filename)
{
    $.ajax({
        url: filename,
        context: elem,
        data: mydata,
        **contentType: false,
        processData: false**
        datatype: "html",
        success: function (data, textStatus, xhr) {
            elem.innerHTML = data;
        }
    });
}
Derly Pacheco
fonte
4
Uma boa resposta é mais do que apenas um snippet de código. Deve explicar porque isso responde à pergunta inicial e fornecer links para a documentação relevante, se disponível.
JSTL de
Sem os dois campos contentTypee processData, o erro continuará aparecendo. Eu adicionei os dois campos e funcionou para mim. Acho que op estava tentando indicar os dois campos importantes.
Ekundayo Blessing Funminiyi
-1
$.ajax({
                    url:"",
                    type: "POST",
                    data: new FormData($('#uploadDatabaseForm')[0]),
                    contentType:false,
                    cache: false,
                    processData:false,
                    success:function (msg) {}
                  });
Nitin Sharma
fonte
7
As respostas são mais úteis se você incluir uma explicação.
Jon B
-2

Experimente isto:

            $.ajax({
                    url:"",
                    type: "POST",
                    data: new FormData($('#uploadDatabaseForm')[0]),
                    contentType:false,
                    cache: false,
                    processData:false,
                    success:function (msg) {}
                  });
Ali Asad
fonte