JQuery: „Uncaught TypeError: Illegal invocation” w żądaniu ajax - kilka elementów

112

Mam dwa wybrane elementy, A i B: kiedy wybrana opcja A ulegnie zmianie, opcje B. muszą zostać odpowiednio zaktualizowane. Każdy element w A implikuje wiele elementów w B, jest to relacja jeden do wielu (A zawiera narody, B powinno zawierać miasta znajdujące się w danej nacji).

Funkcja do_ajaxpowinna uruchomić żądanie asynchroniczne:

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

Aby zaktualizować opcje B, dodałem wywołanie funkcji w onChangezdarzeniu A. Oto funkcja, która działa po wyzwoleniu zdarzenia onChange (of A):

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

}

Czytałem w dokumentach JQuery, że datamoże to być tablica (pary klucz-wartość). Otrzymuję błąd, jeśli wstawię:

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

Zamiast tego nie otrzymuję tego błędu, jeśli moje dane są ciągiem:

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

Ale potrzebuję "wersji tablicowej" zmiennej w moim kodzie PHP po stronie serwera.

Uncaught TypeError: Illegal invocationZnajduje się w „jQuery 1.7.2.min.js” pliku, który jest cały sprężonego, więc nie mogłem dowiedzieć się, jaka część kodu podniesiony błąd.

Czy jest jakieś ustawienie, które mogę zmienić w moim kodzie, aby akceptował dane jako tablicę asocjacyjną?

Nadir Sampaoli
źródło

Odpowiedzi:

151

Dzięki rozmowie z Sarfrazem mogliśmy znaleźć rozwiązanie.

Problem polegał na tym, że zamiast jego wartości przekazywałem element HTML, co tak naprawdę chciałem zrobić (w rzeczywistości w moim kodzie php potrzebuję tej wartości jako klucza obcego do odpytywania mojej citiestabeli i filtrowania poprawnych wpisów).

Więc zamiast:

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

powinno być:

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

Uwaga: sprawdź Jason Kulatunga za odpowiedź , to cytuje JQuery doc wyjaśnić dlaczego przechodząc elementem HTML był przyczyną kłopotów.

Nadir Sampaoli
źródło
dokładnie to, co robiłem. Zapomniałem użyć .val ()
Usman Shaukat
Mijałem opcję wyboru elementu html w zmiennej. Nie zauważyłem, że to nie był zwykły tekst, ale html.
Sterling Diaz
46

Z dokumentacji jQuery dla processData:

processData Boolean
Domyślnie: true
Domyślnie dane przekazane do opcji data jako obiekt (technicznie rzecz biorąc, cokolwiek innego niż łańcuch) będą przetwarzane i przekształcane w ciąg zapytania, dopasowany do domyślnego typu treści "application / x-www -form-urlencoded ". Jeśli chcesz wysłać DOMDocument lub inne nieprzetworzone dane, ustaw tę opcję na false.

Źródło: http://api.jquery.com/jquery.ajax

Wygląda na to, że będziesz musiał użyć processDatado wysłania danych na serwer lub zmodyfikować skrypt php, aby obsługiwał zakodowane parametry kwerendy.

Jason Kulatunga
źródło
1
To prawda. Gdybym mógł to zobaczyć wcześniej, wskazałby mi rzeczywisty błąd w moim kodzie. Dzięki, dodam notatkę do mojej odpowiedzi.
Nadir Sampaoli
25

Otrzymałem ten błąd podczas wysyłania obiektu FormData, ponieważ nie konfigurowałem poprawnie wywołania ajax. Poniższa konfiguracja rozwiązała mój problem.

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
źródło
dzięki. u uratowałem mój dzień i mój problem został rozwiązany przez dodanie „processData: false, contentType: false, cache: false,” w moim treści ajax. Wielkie dzięki.
CumaTekin
11

Czytałem w dokumentacji JQuery, że dane mogą być tablicą (pary klucz-wartość). Otrzymuję błąd, jeśli wstawię:

To jest obiekt, a nie tablica:

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

Prawdopodobnie chcesz:

var data = [{
        'mode': 'filter_city',
        'id_A': e[e.selectedIndex]
}];
Sarfraz
źródło
1
nie zgłasza już tego błędu, ale wygląda na to, że te dane nie są przekazywane do mojej $_GETtablicy po stronie serwera ( var_export($_GET)wyjścia array ( 'undefined' => 'undefined', ))
Nadir Sampaoli
@nadirs: Spróbuj zdefiniować typ metody w swoim module $.ajaxobsługi:type:'get',
Sarfraz
@Sarfraz wynik jest taki sam. Po stronie serwera dataklucze powinny znajdować się w tablicy GET, prawda? A może mimo wszystko są wysyłane inną metodą żądania?
Nadir Sampaoli
@nadirs: Coś takiego działa data: {foo:'myfoo', bar:'mybar'}, myślę, że może być inny problem.
Sarfraz
@Sarfraz Jestem idiotą, wysyłałem obiekt HTML, e[e.selectedIndex]podczas gdy powinienem przekazać jego wartość e[e.selectedIndex].value. Po naprawieniu tej usterki notacja obiektu działa dobrze.
Nadir Sampaoli
7

Niedawno ten sam problem został rozwiązany przez dodanie traditional: true,

deco
źródło
To faktycznie działa, zakładam jednak tylko dla nowoczesnych przeglądarek
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
źródło
4
Dobra odpowiedź jest czymś więcej niż tylko urywek kodu. Powinien wyjaśnić, dlaczego jest to odpowiedź na wstępne pytanie i podać linki do odpowiedniej dokumentacji, jeśli jest dostępna.
JSTL
Bez dwóch pól contentTypei processDatabłąd będzie nadal wyświetlany. Dodałem dwa pola i zadziałało. Myślę, że op próbował wskazać dwie ważne dziedziny.
Ekundayo Blessing Funminiyi
-1
$.ajax({
                    url:"",
                    type: "POST",
                    data: new FormData($('#uploadDatabaseForm')[0]),
                    contentType:false,
                    cache: false,
                    processData:false,
                    success:function (msg) {}
                  });
Nitin Sharma
źródło
7
Odpowiedzi są bardziej pomocne, jeśli dołączysz wyjaśnienie.
Jon B
-2

Spróbuj tego:

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