Jump to content

[Résolu] Afficher des caractéristiques produits sur une image(onMouseover)


Recommended Posts

Bonjour à tous, comme le dit le titre de mon poste, j'aimerai afficher une petite icone à côté de mon "Stock : disponible" qui indiquerait ou est disponible le produit, c'est à dire dans une ville proche de chez le client.

 

J'ai déjà commencé à coder dans le product.tpl ligne 394 :

<span id="availability_label" onMouseOver="Apparaitre()"><img src="{$img_dir}icon\yes.gif"/></span>

 

Maintenant je cherche à savoir si l'on peut insérer du javascript dans le template et si on peut exécuter une requête qui permettra de charger les villes proches du client.

 

Est-ce que quelqu'un pourrait m'aider, svp ?

 

Cordialement

Link to comment
Share on other sites

Bonjour,

 

JQuery est votre amis. Ce plugin est déjà intégré à Prestashop.

 

Il vous suffit de créer un fichier .js, de l'ajouter au chargement de la page avec Tools::AddJS, avec un contenu +/- similaire:

 

<script type="text/javascript">
$(document).ready(function(){
	$('#id_de_mon_bouton").mouseover(function(){
		$.ajax({
			url:			 "mon url vers le fichier de traitement php",
			dataType:		 "json",
			data:			 "mes informations a envoyer comme une url : tata=toto&titi=tutu",
			success:		 function(data){
				alert('succes');
			},
			error:			 function(jqXHR, errorType, errorText){
				alert(jqXHR + ':' + errorType + ':' + errorText);
			}
		});
	});
});
</script>

 

L'url pointe sur votre fichier php qui va traiter les donnés et les renvoyer (en gros, à la fin, vous faites un echo du résultat). Le type de retour est JSON, ce qui veut dire que quand vous ferez l'echo de résultat, il faudra utiliser la fonction json_encode. Dans success, le parametre data est un objet contenant le resultat JSON. Si vous avez par exemple fait ceci :

 

<?php
$array['toto'] = 'tata'
$array['titi'] = 'tutu';
echo json_encode($array);
?>

 

Vous pourrez accéder aux données en faisant :

data.toto

data.titi

 

C'est très simple.

  • Like 1
Link to comment
Share on other sites

Bonjour et merci pour cette réponse très constructive et bien complète, mais j'ai quand même quelques questions à vous posez :

 

- J'aimerai afficher le dépôt de stock d'un produit, donc il faut que je fasse une requête SQL avec cet id produit, je ne sais pas comment le passer dans le fichier php.

 

- Le code javascript que vous avez écrit doit se trouver dans un fichier.js, n'est-ce pas ? Moi j'ai préféré le mettre dans le fichier.tpl pour afficher les produits.

 

- Je n'ai pas compris les informations à envoyer comme une url, qu'est-ce qu'il faut que je mette dedans au juste ?

 

Si vous pouviez m'aider svp. Je vous en serais très reconnaissant.

 

Cordialement.

Link to comment
Share on other sites

- J'aimerai afficher le dépôt de stock d'un produit, donc il faut que je fasse une requête SQL avec cet id produit, je ne sais pas comment le passer dans le fichier php.

 

- Je n'ai pas compris les informations à envoyer comme une url, qu'est-ce qu'il faut que je mette dedans au juste ?

 

Dans le code que j'ai posté, vous devez envoyer les informations à cette ligne :

 

data:				    "mes informations a envoyer comme une url : tata=toto&titi=tutu",

 

Par exemple, vous voulez envoyer l'id du produit, l'id du client et l'id de la langue :

 

data:				    "id_product=" + id_product + "&id_cutomer=" + id_customer + "&id_lang=" + id_lang,

 

Du côté PHP, vous recevrez ça sous forme de variable $_POST :

 

<?php
$id_product = $_POST['id_product'];
$my_super_customer = $_POST['id_customer'];
$language = $_POST['id_lang'];
?>

 

D'ailleurs, par convention, j'ai oublié de mettre le "type" de donnée que reçoit la page PHP, c'est à dire POST :

 

....
type:				  "POST",
url:					 "mon url vers le fichier de traitement php",
dataType:			    "json",
...

 

- Le code javascript que vous avez écrit doit se trouver dans un fichier.js, n'est-ce pas ? Moi j'ai préféré le mettre dans le fichier.tpl pour afficher les produits.

 

Vous pouvez le mettre où vous voulez. Mais je préfère mettre dans un fichier : cela sépare bien les choses. Mais rien ne vous empêche de mettre du code dans les templates. Il faut juste savoir le faire !

  • Like 1
Link to comment
Share on other sites

D'accord, merci des informations, mais malgré tout cela, ça ne fonctionne pas.

Je vous montre mes fichiers :

 

- product.tpl -> ligne 425 à 450

<!-- availability -->
  <p id="availability_statut"{if ($product->quantity <= 0 && !$product->available_later && $allow_oosp) OR ($product->quantity > 0 && !$product->available_now) OR !$product->available_for_order OR $PS_CATALOG_MODE} style="display: none;"{/if}>
<span id="availability_label">{l s='Availability:'}</span>
<span id="availability_value"{if $product->quantity <= 0} class="warning_inline"{/if}>
 {if $product->quantity <= 0}{if $allow_oosp}{$product->available_later}{else}{l s='This product is no longer in stock'}{/if}{else}{$product->available_now}{/if}
</span>
<script type="text/javascript">
 $(document).ready(function(){
  $('#availability_depot').mouseover(function(){
   $.ajax({
	 type:  'POST',
	 url:		_PS_CLASS_DIR_.'Affiche_Depot.php',
	 dataType:   'json',
	 data:	   'id=' + $product->id,
	 success:	function(data){
		   alert('succes');
		},
	 error:	  function(jqXHR, errorType, errorText){
		   alert(jqXHR + ':' + errorType + ':' + errorText);
		}
   });
  });
 });
</script>
<span id="availability_depot"><img src="{$img_dir}icon\yes.gif"/></span>
  </p>

 

- Affiche_Depot.php

<?php
$sql = "SELECT qte_bourg, qte_bron, qte_irigny, qte_etienne, qte_chambery FROM "._DB_PREFIX_."product_quantity WHERE id_product = ".$_POST['id'];
 $req = mysql_query($sql) or die ('Erreur SQL!<br>'.$sql.'<br>'.mysql_error());
 $resultat = mysql_fetch_array($req);
 $qte_bourg = $resultat['qte_bourg'];
 $qte_bron = $resultat['qte_bron'];
 $qte_irigny = $resultat['qte_irigny'];
 $qte_etienne = $resultat['qte_etienne'];
 $qte_chambery = $resultat['qte_chambery'];
 // $qte_valence = $resultat['qte_valence'];

 if($txt_depot == 11){
  if($qte_bourg > 0){
  echo json_encode($qte_bourg);
  }elseif($qte_bron > 0 && $qte_bourg < 0){
echo json_encode($qte_bron);
  }elseif($qte_irigny > 0 && $qte_bron < 0 && $qte_bourg < 0){
echo json_encode($qte_irigny);
  }elseif($qte_etienne > 0 && $qte_irigny < 0 && $qte_bron < 0 && $qte_bourg < 0){
echo json_encode($qte_etienne);
  }else{
echo json_encode($qte_chambery);
  }
 }elseif($txt_depot == 12){
  if($qte_bron > 0){
echo json_encode($qte_bron);
  }elseif($qte_irigny > 0 && $qte_bron < 0){
echo json_encode($qte_irigny);
  }elseif($qte_bourg > 0 && $qte_bron < 0 && $qte_irigny < 0){
echo json_encode($qte_bourg);
  }elseif($qte_etienne > 0 && $qte_irigny < 0 && $qte_bron < 0 && $qte_bourg < 0){
echo json_encode($qte_etienne);
  }else{
echo json_encode($qte_chambery);
  }
 }elseif($txt_depot == 13){
  if($qte_irigny > 0){
echo json_encode($qte_irigny);
  }elseif($qte_bron > 0 && $qte_irigny < 0){
echo json_encode($qte_bron);
  }elseif($qte_bourg > 0 && $qte_bron < 0 && $qte_irigny < 0){
echo json_encode($qte_bourg);
  }elseif($qte_etienne > 0 && $qte_irigny < 0 && $qte_bron < 0 && $qte_bourg < 0){
echo json_encode($qte_etienne);
  }else{
echo json_encode($qte_chambery);
  }
 }elseif($txt_depot == 14){
  if($qte_etienne > 0){
echo json_encode($qte_etienne);
  }elseif($qte_irigny > 0 && $qte_etienne < 0){
echo json_encode($qte_irigny);
  }elseif($qte_bron > 0 && $qte_etienne < 0 && $qte_irigny < 0){
echo json_encode($qte_bron);
  }elseif($qte_chambery > 0 && $qte_irigny < 0 && $qte_bron < 0 && $qte_etienne < 0){
echo json_encode($qte_chambery);
  }else{
echo json_encode($qte_bourg);
  }
 }else{
  if($qte_chambery > 0){
echo json_encode($qte_chambery);
  }elseif($qte_bron > 0 && $qte_chambery < 0){
echo json_encode($qte_bron);
  }elseif($qte_irigny > 0 && $qte_bron < 0 && $qte_chambery < 0){
echo json_encode($qte_irigny);
  }elseif($qte_bourg > 0 && $qte_irigny < 0 && $qte_bron < 0 && $qte_chambery < 0){
echo json_encode($qte_bourg);
  }else{
echo json_encode($qte_etienne);
  }
 }
?>

 

 

Si vous voyez des erreurs, hésitez pas à me corriger. Merci du temps que vous me consacré.

Link to comment
Share on other sites

Aucune erreur affichée ?

 

Si j'ai dit :

 

Il faut juste savoir le faire !

 

C'est qu'il y avait une raison ;) Les accolades ({ et }) sont réservées à Smarty, dans les fichiers templates. De ce fait, en utilisant les accolades pour faire du JavaScript, Smarty tente d'interpréter ce code.. Il faut utiliser les délimiteurs spéciaux de Smarty : {ldelim} pour "{" et {rdelim} pour "}". Vous comprendrez très vite pourquoi je préfère mettre le code JavaScript dans un fichier !

 

Ensuite, un simple avis : un "mouseover" en AJAX, c'est... moyen. Cela veut dire qu'à chaque passage de souris, on fait appel à une requête. Bien sûr ce n'est que mon avis et si votre serveur supporte bien l'envoie ""massif"" de requêtes vous n'aurez aucun soucis.

 

Étant donné que vous ne m'avez linké de message d'erreur (ce qui me semble quand même bizarre du côté de Smarty), je suppose donc que l'erreur vient des accolades. Le reste de votre code me semble correct, mais j'ai pu louper quelque chose. Si vous n'avez pas un alert (success ou error), c'est que peut être vous ne faites pas appel à AJAX. Mettez un alert('toto'); pour voir si le navigateur détecte bien le mouseover.

 

Edit : erreur :

 

data:	 'id=' + $product->id,

 

Avec Smarty, on utilise des point (.). Donc $product.id. De plus, pour montrer à Smarty qu'on veut une variable : {$product.id} :)

  • Like 1
Link to comment
Share on other sites

Bonjour Sbizz, le problème ne doit surement pas venir des accolades car j'ai testé avec le {ldelim} et le {rdelim} et cette fois, il ne m'affiche pas toute la page... J'ai regardé dans Prestashop et je n'ai pas vu de {ldelim}, lors de l'appel d'une fonction, il n'ouvre que les accolades normales. Mais le problème vient du {$product.id} il ne l'accepte pas et ne veut que {$product->id}.

 

Voici mon code avec les accolades {ldelim} et {rdelim} et {$product.id} qui ne m'affiche pas toute la page :

<script type="text/javascript">
 $(document).ready(function(){ldelim}
  $('#availability_depot').mouseover(function(){ldelim}
   $.ajax({
	 type:  'POST',
	 url:	    _PS_CLASS_DIR_.'Affiche_Depot.php',
	 dataType:   'json',
	 data:	   'id=' + {$product.id},
	 success:    function(data){ldelim}
		   alert('succes');
	    {rdelim},
	 error:	  function(jqXHR, errorType, errorText){ldelim}
		   alert(jqXHR + ':' + errorType + ':' + errorText);
	    {rdelim}
   });
  {rdelim});
 {rdelim});
   </script>

 

Sinon je ne sais pas si je vais mettre le code javascript dans une autre page comme vous me l'avez si bien conseillé, car je sens que cela va être bien plus compliqué!

 

Et pour finir je suis toujours coincé, rien ne s'affiche et c'est bien la le problème, encore j'aurais eu un message d'erreur, mais rien!

Link to comment
Share on other sites

Il faudrait afficher les messages d'erreur via le fichier /config/config.inc.php, les deux premières lignes de code (off sur on et false sur true). En espérant que c'est pas déjà fait sinon je vais bloquer :D:ph34r: Edit: et de forcer la compilation Smarty si c'est pas déjà fait via l'administration.

 

Pourquoi passer par un fichier serait plus difficile ?! Il vous suffit de mettre votre code dans un fichier .js, de l'inclure via le controller de la page (c'est facile avec AddJS(..)) et .. voilà. À la limite, le plus chiant dans ce genre de situation, c'est de récupérer les variables, car on ne peut mettre de variable Smarty ou PHP dans ce genre de fichier. Mais pour l'instant on va rester dans le template. D'ailleurs, j'y pense et my bad de pas vous l'avoir dit : je pense que vous êtes dans le fichier product.tpl ? Prestashop a prévu une variable global pour l'id du produit qui se nomme id_product, que vous pouvez donc utiliser directement sans crainte ! D'ailleurs, si vous voulez voir les variables déclarés par Prestashop, le moyen le plus simple c'est d'afficher le code source et de voir les variables JS au début du code source via votre navigateur (clique droit > Code Source).

 

Il vous reste les accolades de l'ouverture et la fermeture de la méthode AJAX :

 

$.ajax({
...
});

 

C'est SUPER bizarre qu'il n'accepte pas $product.id ... pouvez vous faire un die($_POST['id']) dans votre fichier .php ? Voir même de commencer par un die('toto') pour voir si il passe par votre fichier .php.

 

PS: je dis de faire plein de test ; faites les dans l'ordre ;)

  • Like 1
Link to comment
Share on other sites

Je viens de mettre les debug en on et true, rien ne s'affiche de plus.

En fait j'ai vraiment l'impression qu'il n'appel pas le fichier.js et que du coup il ne se passe rien.

J'ai essayé de mettre le AddJS mais dans le fichier ProductController.php qui lui, envoie les fonctions et tout le mécanisme au product.tpl.

Je ne pense pas que l'on puisse appeler un fichier.js depuis un template, non ?

Link to comment
Share on other sites

Sbizz, j'ai du nouveau, j'ai regardé sur le net pour trouver un module qui se rappochait de ce que je voulais et je suis tombé sur "homefeaturedbul".

 

Ce petit module permet l'affichage d'une bulle sur les produit phares, cela affiche les caractéristiques des produits.

 

J'ai pris ces infos et je m'en suis servi pour afficher le dépot. J'ai un petit problème :

 

-fichier.js, regardez à la ligne 21 et dites moi s'il serait possible de mettre dans la variable "depot" le resultat des requetes php que j'effectue dans le fichier.php ?

$(function(){

 var verif = true;
 //RollOver
 $("#availability_depot").mouseover(function(){
  //insert the Bubble span in the code
  $("#availability_depot").append('<span class="bubble"></span>');
  //creation var the ultimate bubble selected
  var bubble = $(".bubble:last");

$(this).parent().find("a").attr("title", "");
//Get a title H5, txt, price in variable
  // var h5 = $(this).parent().find("h5").html();
  // var txt = $(this).prev(".product_desc").html();
  // var price = $(this).next("div span.price").find(".price").html();
(LIGNE 21 -->)var depot = $(this).next("div span.price").find(".price").html();
  // var content = '<strong>' + h5 + '</strong>' +'<br /><i>' + txt + '</i><br />' +  price;
  var content = '<strong>' + depot + '</strong>';

  //Insert content in the Bubble
  bubble.html(content);

  // Animation
  var posLeft = $(this).offset().left-$(this).width()/2 + $(this).width()/4;
  var posTop = $(this).offset().top-$(this).height()/2-bubble.height();
  bubble.css({
left:posLeft,
top:posTop,
opacity:0,
  });
  // Condition for the bug when the bubble is in over
  if( verif == true){
bubble.stop().animate({
 top:posTop+bubble.height(),
 left:posLeft,
 opacity:0.85,
}, 500);

 $(".bubble").mouseover(function(){
   verif = false;
  $(this).stop();
	});

	$(".bubble").mouseout(function(){
   verif = true;
   $(this).stop().animate({
	   opacity:0
	 }, 500, function(){
	$(this).remove();
	 });

	});
  }


 });

//RollOut
 $("#availability_depot").mouseout(function(){
  var bubble = $(".bubble:last");
  var posLeft = $(this).offset().left;
  var posTop = $(this).offset().top;
  verif = true;
  bubble.stop().animate({
 top:posTop-150,
 opacity:0
  }, 500, function(){
bubble.remove();
  });

 });
});

 

J'attends votre réponse avec impatience!

Link to comment
Share on other sites

J'ai reussi à afficher "null"!

http://hpics.li/3642141

 

Alors que j'avais avant :

http://hpics.li/f823488

 

J'ai du modifier :

 

ProductController.php ligne 226->227

//rajout du depot
 'depot' => $this->getDepot($this->product->id, self::$cookie->getDepotClient()),

 

Puis, avec la fonction getDepot qui me retourne le dépôt, ou il y a le plus de quantité, le plus proche du client.

Et la fonction getDepotClient() qui se trouve dans la classe Cookie.php et qui me retourne le dépôt du client.

 

Dans le fichier Affiche_Depot.js, j'ai mis :

var depot = $(this).next("#availability_value1").find(".depot").html();
var content = '<strong>' + depot + '</strong>';

 

Si toutefois je ne vous embete pas avec mes questions, j'aurais deux ou trois petits conseils à vous demander. Merci Sbizz.

Link to comment
Share on other sites

L'histoire du fichier .js me semble bizarre... Pour voir si un fichier est bien inclue (CSS comme JS), il suffit encore une fois d'ouvrir le code source via le navigateur, de trouver le lien vers le fichier et de cliquer dessus et de voir si le contenu est le bon.

 

Je ne pense pas que l'on puisse appeler un fichier.js depuis un template, non ?

 

On a du mal se comprendre : vous avez deux solutions :

- Vous appelez un fichier .js à partir du controller (souvent grâce à setMedia() et à la fonction Tools::addJS()). Ou, si vous faites un module, il faut passer par un hook (celui du header du F.O par exemple, qui se nomme hookHeader) et faire appel à la fonction Tools::addJS().

- Vous mettez votre code JavaScript dans le template de cette manière :

{literal}
<script type="text/javascript">
...
</script>
{/literal}

 

En effet, vous ne pouvez inclure un fichier autre que .tpl dans les templates. Je crois.

 

Si toutefois je ne vous embete pas avec mes questions, j'aurais deux ou trois petits conseil à vous demander. Merci Sbizz.

 

Pas de soucis ^^.

  • Like 1
Link to comment
Share on other sites

Alors j'ai une petite question, comment peut on faire dans le fichier Cookie.php qui se trouve dans le dossier classes, pour créer une fonction qui retrounerai une donnée d'un champ dans la base de données client ?

 

Comme ceci ?

 

public function getDepotClient()
{
 // echo $this->TXT_DEPOT;
		    return $this->TXT_DEPOT;
}

 

Sachant que TXT_DEPOT est un champ que j'ai rajouté afin d'obtenir le dépot du client, qui est un numéro.

 

Donc avec cette fonction, je ne retourne rien. Comment faire ?

Link to comment
Share on other sites

J'ai du mal a comprendre le problème.

 

Vous faites votre requête SQL, vous récupérez donc le champ qui vous intéresse et vous faites retourner cette valeur. Il ne devrait pas y avoir de problème.

 

<?php
public function getDepotClient()
{
$value = Db::getInstance()->getRow('SELECT champ FROM base');
return $value['champ'];
}
?>

 

Après, si vous souhaitez enregistrer cette valeur dans le cookie, je PENSE qu'il suffit simplement de faire :

 

<?php
public function getDepotClient()
{
$value = Db::getInstance()->getRow('SELECT champ FROM base');
$this->NameVariable = $value['champ'];
}
?>

 

Vous devriez donc pouvoir la récupérer en faisant :

 

echo $cookie->NameVariable;

 

Enfin... je pense. La classe cookie possede des setters et des getters. En gros, quand vous faites :

 

$cookie->variable = 1
$cookie->variable;

 

Dans le premier cas elle va faire un appel automatique à la méthode __set et dans le second un appel automatique __get. Cela porte un nom, dont je ne me souviens plus. __set et __get sont comme __construct ; ils sont appelés selon certaines conditions. __construct lors d'une instanciation, par exemple.

 

Ou je n'ai pas compris votre demande O:

  • Like 1
Link to comment
Share on other sites

Okai donc votre solution fonctionne à merveille. Me reste juste un petit problème et après je promet de ne plus vous embêter mon petit Sbizz.

 

Dans le fichier Affiche_Depot.js, je dois récupérer la valeur du dépôt se trouvant dans le fichier product.tpl donc j'ai fait :

 

Affiche_Depot.js ligne 21 et 22

var depot = $(this).next("#availability_value1").find(".$depot").html();
var content = '<strong>' + depot + '</strong>';

 

product.tpl ligne 434 et 435

<span id="availability_value1">{$depot}</span>
<span id="availability_depot"><img src="{$img_dir}icon\yes.gif"/></span>

 

Seulement il me retourne "null" lorsque je passe la souris sur l'image. Avez-vous une idée ?

Link to comment
Share on other sites

Cela me retourne toujours "null". Si j'ai bien compris dans la phrase de code :

var depot = $(this).next("#availability_value1").find(".$depot").html();

 

Le .next() signifie qu'il recherche le span "#availability_value1", le find() qu'il recherche une variable "$depot" et le .html() qu'il affiche son contenue.

 

Dites moi si je me trompe ?

Link to comment
Share on other sites

Pas vraiment.

 

$(this) : on récupère l’élément ciblé. En général quand on utilise this, c'est qu'on applique un événement à un élément qui apparaitra plusieurs fois dans la page (la cible étant souvent la class de la balise). Ici, ça n'a aucune utilité....

next("#availability_value1") : "cherche la prochaine balise ayant l'id availability_value1".

find(".$depot") : c'est une des raisons du pourquoi ça ne marche pas. J'ai l'impression que la personne qui a fait ce code a voulu directement intégrer le JS dans le template et a voulu utiliser les variables smarty. Cela revient a faire $(".$depot"). Donc "trouve toutes les balises ayant la class $depot". Ce qui ne veut rien dire, vu que j'ai rarement vu de dollar dans une classe. Cela ne doit même pas être autorisé par la W3C.

html() : son contenu.

 

L'erreur vient d'autre part, car si cela vous indique NULL, c'est que le JavaScript ne trouve même pas l'élément. Sinon, il afficherait vide.

 

Mon code devrait marcher. J'utilise ça à longueur de journée...

 

Code de test :

 

var depot = $('#availability_value1');
alert(depot);
alert(depot.html());

 

Si possible avoir le code "complet" du JS.

  • Like 1
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...