web-dev-qa-db-fra.com

AJAX) la demande de post n'envoie pas de données

Je travaille sur un site Web Joomla 3.8 sur mon hôte local, hébergé par MAMP 5.1. Je modifie le composant J2Store, qui est construit sur F0F. Veuillez supporter avec moi parce que j'apprends encore beaucoup de ces concepts.

Nous avons une base de données contenant des pièces de voiture ayant 4 propriétés: "constructeur" (ou "marque"), "modèle", "année" et "moteur". Le site Web comporte quatre menus de sélection différents, un pour chaque propriété, qui doivent être sélectionnés dans l'ordre. Par exemple, lorsque l'utilisateur sélectionne une marque, le menu du modèle devient disponible et affiche uniquement les modèles créés par ce fabricant (et de la même manière pour les autres propriétés).

Cette fonctionnalité est déjà implémentée par le développeur précédent sur ce projet, mais elle présente la caractéristique peu pratique que chaque fois qu'un menu de sélection change, il recharge la page entière, ce qui prend un certain temps et est agaçant. J'essaie d'implémenter AJAX les requêtes qui actualisent le contenu du menu sans recharger la page. Mon approche consiste à envoyer une requête lorsqu'un menu change qui demande à la base de données les options appropriées dans le menu suivant, sur la base des choix de menu actuels.

La difficulté que je rencontre est que je ne sais pas comment accéder aux options de menu actuelles dans le code côté serveur. L'ancienne logique du code est basée sur le tableau $ POST [], mais lorsque je consigne le contenu du tableau post pendant mes fonctions de rappel, il est vide ou ne contient pas ce que j'attends/ai besoin.

Le fichier suivant contient mes appels de base de données côté serveur:

/ localhost/my_site/components/com_j2store/models/callback.php

class J2StoreModelCallback extends F0FModel {

    function runCallback($method) {
        switch ($method) {
            case 'getManufacturer':
                $this->getManufacturer();
                break;
            case 'getModel':
                $this->getModel();
                break;
            case 'getManufYear':
                $this->getManufYear();
                break;
            case 'getEngineSize':
                $this->getEngineSize();
                break;
        }
        ...
    }
    ...
    function getModel(){
        // Makes sql query based on the value of $_POST['sel-make']
        ...
    }
    ...
}

Mon code pour une réponse de sélection de menu typique ressemble à ceci:

/ localhost/my_site/media/j2store/js/j2store.js

...

jQuery(document).ready(function() {

  jQuery('#sel-make').change(function() {

    // Reset Model, Year and Engine selects.
    disableSelectMenu('model');
    disableSelectMenu('year');
    disableSelectMenu('engine');

    var selection = jQuery('#sel-make').val();

    // If the user cleared their choice, don't do anything else.
    if (selection === '') {
      return;
    }

    var postData = "sel-make=" + selection;

    // Sends an AJAX request which retrieves the correct contents for the Model select.
    // It passes the response to a helper function.
    jQuery.ajax({
            url: '/my_site/index.php?option=com_j2store&view=callback&task=callback&method=getModel', 
            cache: false,
            type: "POST",
            contentType: "application/json",
            data: postData,
            success: function(response){ 
                // Enables the Model select and fills it with the returned array.
                enableSelectMenu('model', response);
            },
            error: function(xhr, textStatus, errorThrown) {
                console.log("error : " + textStatus);
            }
        });
  });
  ...
}
...

La demande ajax atteint sa destination, mais elle ne conserve pas les informations relatives à la sélection du fabricant. Dans le contexte de getModel, le tableau post est vide et dans le contexte de la méthode runCallback, il est

Array
(
    [option] => com_j2store
    [view] => callback
    [task] => callback
    [method] => getModel
    [Itemid] => 
)

qui n'inclut pas le paramètre de données que j'ai mis dans ma demande. Comment puis-je pousser les sélections de menu vers le modèle (via le contrôleur) via la demande AJAX? Existe-t-il un meilleur moyen d'accéder à ce contenu à partir du code côté serveur?

Je ne sais pas si je ne comprends pas comment envoyer correctement une demande de publication ou si ce type de demande n'est tout simplement pas autorisé dans ce scénario.

4
William

Tout d'abord, puisque vous souhaitez envoyer uniquement une clé supplémentaire + une valeur, vous pouvez l'inclure dans l'URL de l'appel ajax comme suit:

url: '/my_site/index.php?option=com_j2store&view=callback&task=callback&method=getModel&Itemid=' + selection,

Et je ne vois pas pourquoi mais si vous voulez envoyer la valeur choisie avec la clé (sel-make), alors:

url: '/my_site/index.php?option=com_j2store&view=callback&task=callback&method=getModel&sel-make=' + selection,

Si vous envoyez les données incluses dans l'URL, vous pouvez simplement commenter // data: postData. Cette ligne n'est pas réellement nécessaire dans ce cas.

Dans votre fonction runCallback (), vous aurez maintenant les données voulues et vous pourrez l’avoir avec, par exemple, ce qui suit:

function runCallback($method) {

        $app = JFactory::getApplication ();
        $rawDataPost = $app->input->getArray($_POST);
        // if you sent the value in ajax as Itemid:
        $Itemid = $rawDataPost['Itemid'];
        // if you sent it as sel-make:
        $selection = $rawDataPost['sel-make'];
        // then here all of your other things in this function...
}

Ceci est juste un moyen simple de savoir comment vous pouvez l'obtenir. (mon site sur mon localhost a un problème d'encodage pour le moment, je ne peux donc pas essayer ce qui précède, mais je ne vois aucun problème à envoyer Itemid de cette façon à ce modèle via le contrôleur) (mise à jour: maintenant j'ai testé cela et cela travaux).

Et j'ai presque oublié que, si vous voulez plutôt envoyer les données telles que vous les avez formulées à l'origine, vous devez simplement modifier le formatage de la manière suivante:

var postData = {'Itemid' : selection};
3
Zollie