web-dev-qa-db-fra.com

JQuery: 'Uncaught TypeError: Invocation illégale' à la demande ajax - plusieurs éléments

J'ai deux éléments de sélection, A et B: lorsque l'option sélectionnée de A change, les options de B doivent être mises à jour en conséquence. Chaque élément de A implique de nombreux éléments de B, c’est une relation un à plusieurs (A contient les nations, B doit contenir les villes situées dans la nation donnée).

La fonction do_ajax doit exécuter la requête asynchrone:

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

Afin de mettre à jour les options de B, j'ai ajouté un appel de fonction à l'événement onChange de A. Voici la fonction qui s'exécute lorsque l'événement onChange (de A) est déclenché:

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

}

J'ai lu dans documents JQuery que data peut être un tableau (paires clé-valeur). Je reçois l'erreur si je mets:

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

Au lieu de cela, je ne reçois pas cette erreur si mes données sont une chaîne:

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

Mais j'ai besoin de la "version tableau" de la variable, dans mon code php côté serveur.

Le Uncaught TypeError: Illegal invocation se trouve dans le fichier "jquery-1.7.2.min.js", qui est entièrement compressé. Je ne pouvais donc pas savoir quelle partie du code était à l'origine de l'erreur.

Existe-t-il un paramètre que je peux modifier dans mon code afin qu'il accepte les données en tant que tableau associatif?

101
Nadir Sampaoli

Grâce à la conversation avec Sarfraz , nous avons pu trouver la solution.

Le problème était que je passais un élément HTML à la place de sa valeur, ce qui est en fait ce que je voulais faire (en fait, dans mon code php, j'ai besoin de cette valeur comme clé étrangère pour interroger ma table cities et filtrer correctement entrées).

Donc, au lieu de:

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

cA devrait etre:

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

Remarque: vérifiez la réponse de Jason Kulatunga , elle cite le document JQuery pour expliquer pourquoi le passage d'un élément HTML était la cause. troubles.

134
Nadir Sampaoli

À partir de la documentation jQuery pour processData:

processData Booléen
Par défaut: true
Par défaut, les données transmises à l'option data en tant qu'objet (techniquement, autre chose qu'une chaîne) seront traitées et transformées en une chaîne de requête, adaptée au type de contenu par défaut "application/x-www -form-urlencoded ". Si vous souhaitez envoyer un DOMDocument ou d'autres données non traitées, définissez cette option sur false.

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

On dirait que vous allez devoir utiliser processData pour envoyer vos données au serveur, ou modifier votre script php pour prendre en charge les paramètres codés par chaîne de requête.

42
Jason Kulatunga

J'ai lu dans la documentation JQuery que les données peuvent être un tableau (paires clé-valeur). Je reçois l'erreur si je mets:

Cet objet n'est pas un tableau:

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

Vous voulez probablement:

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

Je recevais cette erreur lors de la publication d'un objet FormData parce que je ne configurais pas correctement l'appel ajax. La configuration ci-dessous a corrigé mon problème.

    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); 
            }
        });
10
Mike Volmar

Avait le même problème récemment, résolu en ajoutant traditional: true,

7
deco