Jump to content

Ajax dans prestashop


Recommended Posts

Bonsoir

 

je suis entrain de bosser sur un module et j'ai un gros souci au niveau de l'utilisation d'ajax avec prestashop

 

 

en effet je souhaiterai envoyer une variable depuis mon js vers ma page php en ajax

 

pour l'envoyer je sais comment procéder du moins dans le fonctionnement de base d'ajax c'est à dire :

 

$.ajax({
             type: "POST", // methode de transmission des données au fichier php
             url: "test.php", // url du fichier php
             data: 'id=' + t, // données à transmettre            
       success: function(data){ // si l'appel a bien fonctionné
         //blabla
       }
  });

 

dans mon exemple le test.php est le fichier qui le fichier principal de mon module donc qui est à la racine du module, et dedans j'ai plusieurs fonctions...

 

le problème est que j'arrive pas à récupérer ma variable id transmise par ajax , j'ai vérifier depuis le debug de firefox l'envoi s'est bien déroulé mais avec un $_POST['id'] ou Tools::getValue('id') mais rien à faire c'est tout le temps vide :(

 

quelqu'un aurait une idée de ce qui me manque pour bien récupérer ma variable qui est envoyée depuis js avec ajax ?

 

Merci pour vos piste

Link to comment
Share on other sites

Sinon inspire toi d'un module tel que http://www.coeos.pro/fr/modules-prestashop/118-big-data-les-donnees-sql-en-csv-avec-facilite.html il y a pas mal d'ajax dedans, exemple:

$.ajax({
type: "POST",
headers: { "cache-control": "no-cache" },
url: "'._MODULE_DIR_.$this->name.'/ajax/fichier.php",
data: 	{
		"token" : "'.Configuration::get('token_'.$this->name).'"
	},
success: function(result)
{ 
	//...
},
error: function(result)
{
	//...
}
});
Link to comment
Share on other sites

N'appelez pas le fichier principal de votre module (qui est une classe) mais un fichier à coté: monmodule-ajax.php qui inclut votre classe de module si nécessaire:

<?php

require_once(dirname(__FILE__) . '/../../config/config.inc.php');
require_once(dirname(__FILE__). '/monmodule.php');

... code...

$value1 = Tools::getValue('ma_value1');
...
Link to comment
Share on other sites

 

N'appelez pas le fichier principal de votre module (qui est une classe) mais un fichier à coté: monmodule-ajax.php qui inclut votre classe de module si nécessaire:

<?php

require_once(dirname(__FILE__) . '/../../config/config.inc.php');
require_once(dirname(__FILE__). '/monmodule.php');

... code...

$value1 = Tools::getValue('ma_value1');
...

j'ai crée un autre fichier genre test.php qui est aussi à la racine du module et j'ai fait  comme dans votre code mais ça ne marche pas...

 

dans mon fichier js j'ai ça :

$(document).ready(function() {
    $('#product_1').change(function () {
        var t =  $("#product_1 option:selected").val();
        $.ajax({
            type: 'POST',
            url: '../modules/monmodule/test.php',
            data: {
            "test" : t
            },
            success: function(data)
            {

            }
     });
     
    .trigger('change');
});
});

et dans mon fichier test.php à la racine du module :

require_once(dirname(__FILE__).'../../../config/config.inc.php');
require_once(dirname(__FILE__).'../../../init.php');
require_once(dirname(__FILE__).'/monmodule.php');


$var = Tools::getValue('test');

ddd($var);//debug $var est vide

je me suis trompé quelques part ?

Link to comment
Share on other sites

commence par mettre var t = 'ok';

et url: "'._MODULE_DIR_.$this->name.'/test.php",

tu ne met rien dans success ? rajoute document.getElementById("results").innerHTML = result; avec une div id="results"

et met echo $var dans test.php au lieu de ddd

Link to comment
Share on other sites

bonjour

 

désolé du temps de réponse mais je suis un peu perdu là :(

 

alors j'ai refais des essais mais j'ai un cas de figure bizarre

 

dans mon .JS j'ai ce code là :

$(document).ready(function() {
    $('#product_1').change(function () {
        var t = 'ok';
        $.ajax({
            type: 'POST',
            url: '../modules/monmodule/test.php',//je suis dans un fichier.js        
            //dataType: 'json',
            data: {
            "test" : t
            },
            success: function(data)
            {
              alert('envoi reussi');//ce message est bien apparu après recharge de la page donc pas de souci d'envoi
            }
     });
       
        alert(t);
 
    })
    .trigger('change');
});

 en fait quand je regarde dans mon debug de firefox j'ai bien une réponse 200 ce qui veut dire que l'envoi s'est bien passé sauf que quand je fais un echo dans mon test.php

qui contient ça :

require_once(dirname(__FILE__).'../../../config/config.inc.php');//cest le bon niveau

$var = Tools::getValue('test');

echo($var);

bah là il m'affiche rien du tout mon echo et pourtant j'ai une réponse de 200...

 

si vous avez une idée du comment :)

 

Et aussi j'ai une question dans le cas je voudrais récupérer ma variable mais directement dans mon fichier module par exemple dans une function getId() qui est definie est ce que c'est possible de ciblé mon envoi non seulement dans mon fichier.php mais aussi qu'il soit réceptionner dans ma fonction souhaitée ?

Link to comment
Share on other sites

En respectant strictement le code ci-dessus, les requêtes test.php (1 au chargement de la page + 1 à chaque modif+validation du champ #product_1) répondent avec le contenu du fichier test.php ("require_once( ... echo($var);"). En ajoutant <?php au début de test.php, elles répondent bien "ok".

 

Question très bête: vous regardez bien la réponse dans l'outil d'inspection Réseau, onglet Réponse, n'est-ce pas?

Parce qu'on est d'accord, rien n'est prévu pour le moment pour afficher de quelque manière que ce soit la réponse dans la page.

 

Link to comment
Share on other sites

En respectant strictement le code ci-dessus, les requêtes test.php (1 au chargement de la page + 1 à chaque modif+validation du champ #product_1) répondent avec le contenu du fichier test.php ("require_once( ... echo($var);"). En ajoutant <?php au début de test.php, elles répondent bien "ok".

 

Question très bête: vous regardez bien la réponse dans l'outil d'inspection Réseau, onglet Réponse, n'est-ce pas?

Parce qu'on est d'accord, rien n'est prévu pour le moment pour afficher de quelque manière que ce soit la réponse dans la page.

 

oui je regarde bien dans l'outil d'inspection réseau de firefox...

 

mais du coup moi ce qui m'intéresse c'est de pouvoir l'afficher sur ma page parce que c'est une info qui me seras utiles comment je dois faire dans ce cas ?

Link to comment
Share on other sites

La réponse sera passée en argument de la fonction success (ligne 11: data). Vous pouvez en faire ce que vous voulez en js. Par exemple ouvrir un popup si c'est une message à destination de l'utilisateur, l'insérer dans votre page si c'est un bloc html, ou mettre à jour un champ de la page si c'est une valeur.

 

Mais il faudrait d'abord que vous la récupériez, ce qui ne semble pas être le cas...

 

Supprimer la ligne alert(t); et remplacez alert('envoi reussi'); par alert(data);

Que se passe-t-il au chargement de la page et lors d'une modif du champ?

 

 

Link to comment
Share on other sites

La réponse sera passée en argument de la fonction success (ligne 11: data). Vous pouvez en faire ce que vous voulez en js. Par exemple ouvrir un popup si c'est une message à destination de l'utilisateur, l'insérer dans votre page si c'est un bloc html, ou mettre à jour un champ de la page si c'est une valeur.

 

Mais il faudrait d'abord que vous la récupériez, ce qui ne semble pas être le cas...

 

Supprimer la ligne alert(t); et remplacez alert('envoi reussi'); par alert(data);

Que se passe-t-il au chargement de la page et lors d'une modif du champ?

avec ce code js là :

$(document).ready(function() {
    $('#product_1').change(function () {       
        var t = 'ok';
        $.ajax({
            type: 'POST',
            url: '../modules/customizer/test.php',       
           
            data: {            
            "test" : t
            },
            success: function(data)
            {
              alert(data);
             $('#color_1').css('display','none');

            }
     });
        
 
    })
    .trigger('change');
});

l'alert m'affiche(ok) 

 

dans mon test.php j'ai mis ça :

require_once(dirname(__FILE__).'../../../config/config.inc.php');

$t = Tools::getValue('test');

	echo $t;

mais ce qui me pose problème c'est que j'arrive toujours pas a affcihé mon echo $t quand je check l'url qui mène à ma page test.php bah elle est toujours vierge et je pense pas avoir mal fait un truc ...  :huh:

Link to comment
Share on other sites

quand je fais http://monsite.com/m...t.php?test=toto là j'ai bien un retour de mon echo qui m'affiche toto donc mon Tools::getValue('test') contient la valeur qui vient de mon js c'est déjà ça :)

 

mais est ce que ce meme code (coté js ) marcherai sur mon fichier principal de mon module sachant que dedans j'ai beaucoup de fonction ? pour rappel test.php est juste un fichier à la racine qui n'a rien à voir avec le fonctionnement du module

Link to comment
Share on other sites

Oui, à la condition par exemple d'ajouter un paramètre ajax=1 et de coder correctement la classe principale du module. Tu peux t'inspirer pour ça de modules/contrôleurs existants (cherche ceux qui définissent une méthode du genre processAjax). Sinon tu peux conserver ton script séparé, y inclure tout ce qu'il faut et appeler les fonctions qui vont bien.

Link to comment
Share on other sites

Bonjour

 

je reviens vers vous parce que mon problème n'est toujours pas résolu :(

 

alors j'ai refais des recherches etc etc et donc je veux garder mon script séparé et l'appeler dans mon fichier principal du module.

 

donc en gros dans mon fichier.js j'ai ça :

$(document).ready(function() {
	$('#product_1').change(function () {
      t =  $("#product_1 option:selected").val();	
		
		$.ajax({
			type: "POST",
			url: '../modules/customizer/test.php',
			data: { 
          ajax:true,        
          action: 'getId',
          ok:t
           },
			success: function(data) {
          alert(data);						
			}
		});
	})
	  .trigger('change');

});

dans mon fichier test.php (qui est à la racine de mon module)

include_once(dirname(__FILE__).'/../../config/config.inc.php');
include_once(dirname(__FILE__).'/../../init.php');

class Test{
	public function getId(){
	// Ajax query
	$test = Tools::getValue('ok');
			 echo ($test);

    }        
}

et enfin dans mon fichier principal du module qui est à la racine j'ai inclus mon test.php

include_once(dirname(__FILE__).'/../../config/config.inc.php');
include_once(dirname(__FILE__).'/../../init.php');
include_once(dirname(__FILE__).'/test.php');
.
.
.
.
.
 $ok = new Test();
  ddd($ok->getId());//cette ligne n'affiche rien....

d'après ces infos à quel niveau j'ai loupé un truc pour qu'il m'affiche rien depuis mon fichier principal du module ??

Link to comment
Share on other sites

Dans ce cas là, l'URL à fournir à $.ajax n'est plus "../modules/customizer/test.php", mais "../modules/customizer/customizer.php", en supposant que le fichier principal du module s'appelle customizer.php C'est dans ce fichier là que le traitement est maintenant réellement fait (lignes 9 et 10). Le fichier test.php ne fait que définir la classe Test.

Link to comment
Share on other sites

Merci pour ta réponse mais le problème est que je veux que le traitement se fasse dans le test.php

 

donc dedans j'ai :

<?php
include_once(dirname(__FILE__).'/../../config/config.inc.php');
include_once(dirname(__FILE__).'/../../init.php');
//include_once(dirname(__FILE__).'/../../classes/Cookie.php');
include_once(dirname(__FILE__).'/customizer.php');



class Test{
	public function getId(){		
	// Ajax query
	$test = Tools::getValue('ok');
			 echo ($test);
	

    }        
}

?>

et dans mon fichier.js

$(document).ready(function() {
	$('#product_1').change(function () {
      t =  $("#product_1 option:selected").val();	
     // $.cookie("test2", t);
		
		$.ajax({
			type: "POST",
			//url: '../modules/customizer/test.php',
      url: '../modules/customizer/test.php',
			data: { 
          ajax:true,        
          action: 'getId',
          ok:t
           },
			success: function(data) {
          alert(data);
        					
			}
		});
	})
	  .trigger('change');

});

mais là mon alert affiche vide et je vois pas d'ou vient le soucis :(

Link to comment
Share on other sites

Dans ce cas:

  1. Supprime les lignes 9 et 10 du fichier principal
  2. Pas besoin du paramètre ajax: true dans la requête (il sert si la requête est dirigée vers le module ou un contrôleur)
  3. Code effectivement le traitement de la requête dans test.php

Par exemple, en conservant ce qui est déjà en place:

<?php
include_once(dirname(__FILE__).'/../../config/config.inc.php');
include_once(dirname(__FILE__).'/../../init.php');

class Test {
    public function getId() {
        $test = Tools::getValue('ok');
        echo($test);
    }
}

$action = Tools::getValue('action');
if ($action) {
    $test = new Test();
    $test->$action();
}

Sur réception de la requête:

  1. Le fichier test.php va être exécuté
  2. La classe Test va êtré déclarée
  3. Le paramètre action va être récupéré et, si il est défini, une instance de la classe Test va être créée et la méthode correspondant au paramètre va y être exécutée

 

Link to comment
Share on other sites


$.ajax({

    type: "POST",

    url: '../modules/customizer/test.php',

    data: {

        ajax: true,

action: 'getId', /* <== CECI */

        ok: t

    },

    success: function(data) {

        alert(data),

    }

});

Link to comment
Share on other sites

 

Dans ce cas:

  1. Supprime les lignes 9 et 10 du fichier principal
  2. Pas besoin du paramètre ajax: true dans la requête (il sert si la requête est dirigée vers le module ou un contrôleur)
  3. Code effectivement le traitement de la requête dans test.php

Par exemple, en conservant ce qui est déjà en place:

<?php
include_once(dirname(__FILE__).'/../../config/config.inc.php');
include_once(dirname(__FILE__).'/../../init.php');

class Test {
    public function getId() {
        $test = Tools::getValue('ok');
        echo($test);
    }
}

$action = Tools::getValue('action');
if ($action) {
    $test = new Test();
    $test->$action();
}

Sur réception de la requête:

  1. Le fichier test.php va être exécuté
  2. La classe Test va êtré déclarée
  3. Le paramètre action va être récupéré et, si il est défini, une instance de la classe Test va être créée et la méthode correspondant au paramètre va y être exécutée

 

bonjour

 

je viens d'essayer le code ça marche merci en tout cas :)

 

j'ai juste un petit problème now quand j'essaye d'envoyer une variable vers une page tpl ça ne marche pas...

voici le contenu de ma page test.php

<?php
include_once(dirname(__FILE__).'/../../config/config.inc.php');
include_once(dirname(__FILE__).'/../../init.php');
include_once(dirname(__FILE__).'/customizer.php');


class Test{
	public function getId(){		
	$test = Tools::getValue('ok');
	echo ($test);

	$custo = new Customizer();
	$color = $custo->getColor($test);//couleur de l'element select
	
	global $smarty;
	$smarty->assign('color', $color);//variable a envoyé dans form.tpl
	$smarty->display(__FILE__,'/views/templates/admin/_configure/helpers/form/form.tpl');
	

    }

    
    
}

$action = Tools::getValue('action');
if ($action) {
    $test = new Test();
    $test->$action();
}


?>

le problème ici j'ai un alert qui m'affiche le contenu de ma page test.php (le code au dessus)

 

et après j'ai un message me disant :

Notice à la ligne 238 du fichier /home/XXXXXXXX/prestashop/cache/smarty/compile/58/b4/96/58b4961d4514331893027fa28e66e1b76090c56b.file.form.tpl.php
[8] Undefined index: color

Notice à la ligne 238 du fichier /home/XXXXXXXX/prestashop/cache/smarty/compile/58/b4/96/58b4961d4514331893027fa28e66e1b76090c56b.file.form.tpl.php
[8] Trying to get property of non-object

une idée sur le fait que mon assign marche pas comme il faut ?

Link to comment
Share on other sites

Oui...

Déjà global $smarty on oublie depuis la 1.5

Ensuite, assign() attend un array, pas autre chose.

 

Donc:

$context = Context::getContext();
$smarty = $context->smarty;

$smarty->assign(array('color' => $color));

Ca devrait aller un peu mieux

Link to comment
Share on other sites

merci je viens de changer mais j'ai les même erreurs :

$context = Context::getContext();
$smarty = $context->smarty;
$smarty->assign(array('color' => $color));//variable a envoyé dans form.tpl
$smarty->display(__FILE__,'/views/templates/admin/_configure/helpers/form/form.tpl');

pour info mon fichier test.php est à la racine de mon module donc c'est pas le fichier principal ni controller ni override est que le problème vient pas de là ?

Link to comment
Share on other sites

Ah ben là ca ne marchera jamais.

 

Je ne crois pas que vous comprenez comment ça marche. Là vous essayez d'envoyer une variable smarty à un tpl qui est déjà exécuté, donc il ne se passera rien.

 

Dans l'ordre:

Supprimez votre variable $color du tpl, elle ne sert à rien.

Si votre retour ajax donne un résultat, vous utilisez javascript pour modifier l'affichage, c'est comme ça que cela fonctionne.

Si vous voulez utiliser smarty il faudra recharger la page (ou au moins une partie)

Link to comment
Share on other sites

C'est le but, non ?

 

Ajax explication:

 

Fonctionnement classique d'une page:

  1. l'internaute envoie des données (ou pas)
  2. php génère le code et l'envoie à smarty
  3. smarty génère du html avec ces données
  4. Le tout est envoyé à l'internaute.

A ce moment là, la connexion internaute/serveur est terminée.

 

Si vous voulez que les données de la page soient modifiées en temps réel, sans recharger la page, c'est là qu' Ajax intervient (Asynchrone Javascript Xhtml)

  1. Javascript, qui n'a pas le droit de modifier quoique ce soit sur le serveur, appelle un fichier php en lui envoyant des données (en GET ou POST)
  2. PHP interprète ces données et renvoie sa réponse à javascript
  3. Javascript reçoit donc des data qu'il peut injecter dans le html (et donc modifier l'affichage chez l'internaute)
Link to comment
Share on other sites

ça y est j'ai trouvé la fonction ajax pour faire le traitement :)

 

mais j'ai un dernier point qui me fait la misère depuis des heures je veux récuperer  le contenu d'un <li> à chaque fois qu'on click dessus mais ma fonction js marche qu'une seule fois... c'est à dire quand je click la première fois mais après quand je reclick dessus j'ai pas d'alert... voici mon code

$(document).ready(function() {
  $('#color_to_pick_list li').click(function() {

    var col1 =  $('#color_to_pick_list li.selected a.selected').attr('data-id-attribute');

    alert(col1);
  })
  

});

comment faire pour que à chaque click j'ai mon alert qui m'affiche la valeur de mon li qui a la class selected ??

Link to comment
Share on other sites

C'est pas gagné! C'est bien ce que je pensais: tout le bloc qui contient les éléments auxquels vous attachez le callback est remplacé après le premier clic (requête ajax qui ramène un bloc html), et donc votre callback est perdu.

 

Je comprends que vous voulez légèrement modifier le comportement du module existant. Le mieux serait d'agir directement au sein de son propre code JS. pm_advancedpack/js/pack.js, ligne 528: le bloc est remplacé. Ajoutez votre traitement, en appelant par exemple une fonction définie dans votre propre JS. Par contre, ce n'est plus le moment de recoller un callback sur click parce qu'à ce moment-là, la couleur a déjà été sélectionnée.

 

Link to comment
Share on other sites

ah je comprend mieux pourquoi ma fonction js marchait pas... du coup je vais essayer de creuser du coté pack.js il devrais y avoir un moins parce qu faut que je récupère id_color qui select...

 

merci pour l'info en tout cas je ferais un retour si j'ai quelques choses :)

Link to comment
Share on other sites

C'est pas gagné! C'est bien ce que je pensais: tout le bloc qui contient les éléments auxquels vous attachez le callback est remplacé après le premier clic (requête ajax qui ramène un bloc html), et donc votre callback est perdu.

 

Je comprends que vous voulez légèrement modifier le comportement du module existant. Le mieux serait d'agir directement au sein de son propre code JS. pm_advancedpack/js/pack.js, ligne 528: le bloc est remplacé. Ajoutez votre traitement, en appelant par exemple une fonction définie dans votre propre JS. Par contre, ce n'est plus le moment de recoller un callback sur click parce qu'à ce moment-là, la couleur a déjà été sélectionnée.

finalement j'ai fait comme ça dans le pack.js y avait une fonction qui recupérer bien l id couleur au clic donc j'ai juste ajouter une fonction ajax pour récuperer ce dernier encore merci :)

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...