Jump to content

[RESOLU] Panier : remplacer boutons (+ -) par menu déroulant


Recommended Posts

Bonjour à tous,

 

ne trouvant rien sur la toile de bien explicite, je post donc ce topic.

 

En fait, certains de mes produits, sont vendus selon un choix de quantité (100, 250, 500 & 1000) et d'autres à l'unité.

 

Côté produit c'est impeccable, ma quantité se change bien en menu déroulant ou en champ (pour la saisie) selon le produit sélectionné.

 

Mais côté panier, je voudrais (toujours selon le produit) pouvoir afficher le même menu déroulant.

 

J'ai beau examiner le fichier blockcart.tpl mais je ne trouve ni les boutons ni un href correspondant à mes +- afin d'y faire mes modifs.

 

Si quelqu'un peu m'éclairer un peu ce serait super.

 

Merci d'avance

 

 

Edited by frieurieud (see edit history)
Link to comment
Share on other sites

Bonjour,

 

Pas sûr de pouvoir aider beaucoup car à mon avis ta demande n'est pas si simple...

 

Quelle est ta version de Prestashop?

 

Je ne vois déjà pas très bien comment fonctionne ton choix de quantités sur la page produit... Tu as fait une modif perso pour ça ou ton choix de quantités est en réalité un choix de déclinaisons? Tu aurais un lien vers ta boutique pour voir ça en démo?

 

Sinon concernant les +/-, le fichier blockcart.tpl correspond en fait au bloc panier et non pas au résumé du panier du processus de commande.

 

C'est donc dans le fichier shopping-cart-product-line.tpl que tu dois regarder... mais certainement aussi dans cart-summary.js

 

Mais je le répète, je doute fort que ce soit évident à faire...

Link to comment
Share on other sites

Bonjour Zebx et merci pour ta réponse,

 

J'utilise ps 1.5.6.2

 

En fait j'ai modifier product.tpl avec une condition qui me permet d'identifier quel produit a été selectionné :

{if ($product->id == 8) OR ($product->id == 9)}

puis dans cette condition on place un menu déroulant contenant des chiffres :

<label>{l s='Quantity:'}</label>
<select name="qty" id="quantity_wanted"> <option>100</option> <option>250</option> <option>500</option> <option>1000</option> </select>

la partie else affiche la quantité avec son champs tel qu'on le connait (le client y entre ses quantités).

 

Cette partie là fonctionne très bien, mais si le premier choix a été ajouté à mon panier, je ne souhaite pas que l'on puisse incrémenter de un en un mais plutôt afficher le même menu déroulant avec ses quantité prédéfinis.

 

Logiquement je devrais pouvoir faire la même chose qu'avec product.tpl et le .tpl que je recherche.

Je vais donc étudier la chose avec tes indications.

 

Sinon tu le lien de ma boutique est http://www.printissimo.fr.

Dans la catégorie Affiches, les produits ont le menu déroulant, les autres le champs texte.

 

Merci

 

Je reviendrais... B)

Link to comment
Share on other sites

Ok, je comprends mieux :)

 

Ce n'est pas une modification globale mais tu gères donc les cas particuliers, et s'il y en a peu, pourquoi pas en effet...

 

A priori tu devrais pouvoir faire la même chose dans le tpl que je t'ai indiqué, la difficulté sera cependant peut-être dans le js car c'est lui qui gère le recalcul des montants à la volée... mais normalement rien d'insurmontable ;)

Link to comment
Share on other sites

Bon voilà où j'en suis.

 

J'ai mis la même condition dans le tpl et avec quelques modifs (à partir de la ligne 54 pour ceux que ça interresse):

{if ($product.id_product == 8) OR ($product.id_product == 9)}
    <div class="cart_quantity_button">
	<input type="hidden" value= ... Ces 2 input pour l'affichage de la quantité />
	<input size="2" type="text" ... que je n'ai pas touché />
     <br/><br/>
     <p>
	Autre Qté :<br/>
	<select name="quantite_defini" id="quantite_defini"> <option value=100>100</option> <option value=250>250</option> <option value=500>500</option> <option value=1000>1000</option> </select>
     </p>
     </div>
{else}
... sinon affichage normal avec les boutons +-

 j'ai bien mon menu déroulant selon les cas.

 

Maintenant je voudrais pouvoir envoyer la valeur selectionnée vers cart-summary.js ...  :unsure:

 

Quand j'examine le code d'envoi pour une incrémentation et bien ... je n'y comprend rien  :D

<a
    rel="nofollow" class="cart_quantity_up"
    id="cart_quantity_up_{$product.id_product}_{$product.id_product_attribute}_{if $quantityDisplayed > 0}nocustom{else}0{/if}_{$product.id_address_delivery|intval}"
    href="{$link->getPageLink('cart', true, NULL, "add=1&id_product={$product.id_product|intval}&ipa={$product.id_product_attribute|intval}&id_address_delivery={$product.id_address_delivery|intval}&token={$token_cart}")|escape:'html'}"
    title="{l s='Add'}">
    <img src="{$img_dir}icon/quantity_up.gif" alt="{l s='Add'}" width="14" height="9" />
</a>

Déja dois changer "cart_quantity_up" par "cart_quantity_change" par exemple qui sera ajouté au js (mais dois-je l'ajouter ailleurs ?)

Dans le js il faut créer une fonction exprès-pour afin de récupérer la valeur et la traiter.

Par contre je ne sais pas du tout comment envoyer cette valeur.

J'ai fait des essais divers et variés mais je n'ai pas l'habitude de ce genre d'écriture.

 

Quelqu'un aurait-il une piste ?

 

Merci et à bientôt ... je reviendrais  :ph34r:

Link to comment
Share on other sites

Je pige pas bien, dan ton code il me semble que le champ input text est toujours présent, or c'est lui qui doit être remplacé par ton select.

 

Tes boutons + -, eux doivent seulement disparaître selon le cas.

 

Pour le js tu dois donc aussi plus t'inspirer du fonctionnement du champ input text que des boutons.

 

La classe de ton select doit donc être changée en effet, du style cart_quantity_select.

 

Ensuite dans le js, au début du fichier tu as des handlers, qui se déclenchent sur des événements précis.

		$('.cart_quantity_input').typeWatch({ highlight: true, wait: 600, captureLength: 0, callback: function(val) { updateQty(val, true, this.el) } });

Ca c'est pour le champ texte par exemple.

 

Tu dois donc en ajouter un pour ton select lorsqu'il change : http://api.jquery.com/change/

 

Après y a d'autres modifs encore à faire dans le js... si tu fais une recherche dans le fichier de "cart_quantity_input" tu peux voir à quels endroits tu devrais sans doute aussi intervenir.

 

Ce ne sont que des pistes hein... après si tu ne maîtrises pas plus que ça la compréhension du code, ça risque d'être plus compliqué que prévu :unsure:

 

Auquel cas, il sera peut-être préférable pour toi de juste désactiver le champ input text du panier, plutôt que de le remplacer par un select... certes c'est moins bien, mais c'est beaucoup plus simple :)

  • Like 1
Link to comment
Share on other sites

Salut Zebx,

 

En fait je voulais laisser afficher le prix (donc les input) et placer en dessous mon menu déroulant afin d'en choisir un autre.

Mais ta remarque m'a fait réfléchir et il parait inutile d'afficher le prix étant donné que c'est le menu déroulant qui le fera en affichant la bonne sélection.

 

Je vais étudier tes pistes...mais comme tu dis c'est pas gagné  :huh:

 

Merci à toi pour toutes ces infos.

 

I'll be back  B)

Link to comment
Share on other sites

Salut à tous,

 

J'ai trouvé une piste sur ce lien. C'est un code qui modifie 'shopping-cart-product-line.tpl' et 'Cart.php'.

Cela remplace la quantité et les boutons +- par un champs texte et un bouton update. Le but est qu'après avoir entré une quantité dans le champ, on clique sur le bouton afin d'effectuer les changements.

Bien entendu elle ne fonctionne pas sur ps 1.5 (ce serait trop facile  :D ).

 

Voici les bouts de codes :

 

shopping-cart-product-line.tpl

<form action="{$base_dir}cart.php" method="post">
	<input type="hidden" name="token" value="{$token_cart}" />
	<input type="hidden" name="id_product" value="{$product.id_product|intval}" />
	<input type="hidden" name="add" value="1" />
	<input type="hidden" name="ipa" value="{$product.id_product_attribute|intval}" />
	<input type="hidden" name="op" value="setto" />
	<input size="4" type="text" name="qty" class="text" value="{$product.cart_quantity-$quantityDisplayed}"/><br/>
	<p><input type="submit" name="Submit" value="{l s='Update'}" /></p>
</form>

Cart.php

Ce code se place juste après "else if ($operator == 'down')"

else if ($operator == 'setto')
{
	$result2 = Db::getInstance()->getRow('
		SELECT '.($id_product_attribute ? 'pa' : 'p').'.`quantity`, p.`out_of_stock`
		FROM `'._DB_PREFIX_.'product` p 
		'.($id_product_attribute ? 'LEFT JOIN `'._DB_PREFIX_.'product_attribute` pa ON p.`id_product` = pa.`id_product`' : '').'
		WHERE p.`id_product` = '.(int)$id_product.
		($id_product_attribute != NULL ? ' AND `id_product_attribute` = '.(int)$id_product_attribute : ''));

     $product_qty = (int)$result2['quantity'];
     $new_qty = (int)$quantity;
     $qty = (int)$quantity;
     if (!Product::isAvailableWhenOutOfStock(intval($result2['out_of_stock'])))
     if ($new_qty > $product_qty)
	return false;
} 

Donc là j'étudie la requête afin de voir se qu'elle me retourne. Je voudrais donc la convertir en sql et la tester sur mysql.

 

Mais...(parcequ'il y a un mais, sinon je ne serais pas là  :P )...je ne trouve nul part sur le net l'explication de cette ecriture : 

($id_product_attribute ? 'pa' : 'p').'.`quantity`,

Je sais que "$id_product_attribute" correspond à l'id de la déclinaison, que "pa" correspond à la table product_attribute et "p" à la table product, mais je ne comprend pas à quoi sert le ? et les : (et en plus ce type d'écriture est utilisé encore 2 fois... :huh: )

 

En cadeau un superbe, que dis-je, un magnifique "merci" sera attribué au grand vainqueur de ce concours des devinettes  :D .

 

De retour, bientôt, je serai  :ph34r:

Link to comment
Share on other sites

Comme quoi on en apprend tout les jours...moi je suis de la vieille école avec mon if-then-else  :)

 

Booon ça me permet de comprendre un peu mieux le déroulement de la requete...

 

Et notre grand gagnant du concours des devinettes est...(roulement de tambour)...ZEBX (applaudissement de la foule en délire)

qui remporte ce magnifique...

 

MEEEEERRCIIIIIIIIIIII !

Link to comment
Share on other sites

CA Y EST CA FONCTIONNE !!!  ^_^

 

Je vais reprendre ici le but de ma demande et le comment j'ai fait.

 

Tout d'abord grand merci à Wireaudio et à PatriceVigier qui ont donné la plus grande partie de la solution sur ce post.

 

But : 

 

Dans la partie récapitulatif de la commande, remplacer les boutons +- par

1- un champ texte dans lequel le client peut modifier sa quantité (pour les produits qui ne se vendent qu'en petites quantités, c-à-d moins de 10)

 

2- un menu déroulant imposant des quantités (pour les produits qui ne se vendent qu'avec des quantités plus importantes 100, 500, 1000, 10 000 par ex des affiches dans mon cas).

 

 

 

Fait sous Prestashop 1.5.6.2 (je vous laisse tester les autres versions 1.5 voir 1.6)

 

 

Nous allons modifier 2 fichiers : VotreBoutique\classes\Cart.php et VotreBoutique\themes\VotreTheme\shopping-cart-product-line.tpl

 

hopping-cart-product-line.tpl

<!-- script à placer en début de code -->
<script type='text/javascript' charset='utf-8'>
	{literal}
	function required()
	{
		var len = document.getElementsByName('qty').length;
		var txtValue = document.getElementsByName('qty');
		var i = 0;
		while (i<len || txtValue[i].value >0)
		{
			if((txtValue[i].value == 0) || (txtValue[i].value == "0") || (txtValue[i].value == ""))
			{
		           //alert("{/literal} {l s=' Quantity zero is not allowed, to delete the product, \n click on delete function located on the right of the line.'} {literal}");
			   alert("La quantité à zéro n\'est pas autorisée, \n pour supprimer l\'article, \n cliquez sur la fonction supprimer, à droite de la ligne.");			  
			   txtValue[i].focus();
			   return false;
			   break;
			}
			i++
		}
	}
	{/literal}
</script>


<!-- rechercher : <td class="cart_quantity" et remplacer tout le td par le code qui suit.
Ne pas effacer le bloc <td class="cart_total"> -->
	
	<td class="cart_quantity"{if isset($customizedDatas.$productId.$productAttributeId) AND $quantityDisplayed == 0} style="text-align: center;"{/if}>
		{if isset($customizedDatas.$productId.$productAttributeId) AND $quantityDisplayed == 0}<span id="cart_quantity_custom_{$product.id_product}_{$product.id_product_attribute}" >{$product.customizationQuantityTotal}</span>{/if}
		{if !isset($customizedDatas.$productId.$productAttributeId) OR $quantityDisplayed > 0}			
				<form name = "form1"  onsubmit="return required(document.form1.qty)" action="{$base_dir}cart.php" method="post" >
					<input type="hidden" name="token" value="{$token_cart}" title="token"/>
					<input type="hidden" name="id_product" value="{$product.id_product|intval}" title="id product"/>
					<input type="hidden" name="add" value="1" title="add"/>
					<input type="hidden" name="ipa" value="{$product.id_product_attribute|intval}" title="id product attribute"/>
					<input type="hidden" name="op" value="setto" title="op"/>
					<input type="hidden" value="{if $quantityDisplayed == 0 AND isset($customizedDatas.$productId.$productAttributeId)}{$customizedDatas.$productId.$productAttributeId|@count}{else}{$product.cart_quantity-$quantityDisplayed}{/if}" name="quantity_{$product.id_product}_{$product.id_product_attribute}_{if $quantityDisplayed > 0}nocustom{else}0{/if}_{$product.id_address_delivery|intval}_hidden" />
					
					<!-- Affichage du menu déroulant ou non selon l'id_product-->
					{if ($product.id_product == 8) OR ($product.id_product == 9)}
						<input size="2" type="text" autocomplete="off" class="cart_quantity_input" value="{if $quantityDisplayed == 0 AND isset($customizedDatas.$productId.$productAttributeId)}{$customizedDatas.$productId.$productAttributeId|@count}{else}{$product.cart_quantity-$quantityDisplayed}{/if}"  name="quantity_{$product.id_product}_{$product.id_product_attribute}_{if $quantityDisplayed > 0}nocustom{else}0{/if}_{$product.id_address_delivery|intval}" />
						<br/><br/>
						<label>{l s='Autre choix :'}</label><br/>
						<select name="qty" id="quantity_wanted"> <option value=100>100</option> <option value=250>250</option> <option value=500>500</option> <option value=1000>1000</option> </select>
						<input class="cart_quantity_udate" type="image" title="{l s='Update quantity'}" src="{$img_dir}icon/refresh.gif" alt="{l s='Update'}" width="16" height="16" />
					{else}
						<input align="left" type="text" name="qty" class="cart_quantity_input" value="{$product.cart_quantity-$quantityDisplayed}" size="1" maxlength="2" onblur="required(document.form1.qty)"/>
						<input class="cart_quantity_udate" type="image" title="{l s='Update quantity'}" src="{$img_dir}icon/refresh.gif" alt="{l s='Update'}" width="16" height="16" />
					{/if}
				</form>
		{/if}
	</td>

2 choses importantes : En haut du code la partie javascript empeche l'envoi d'une quantité à Zéro

                                     La partie <td class="cart_quantity"  gère l'affichage du menu déroulant ou du champ texte grâce à la condition {if ($product.id_product == 8) OR ($product.id_product == 9)} id.product étant l'identifiant de mon article. Ici si c'est l'article 8 ou 9 alors placer le menu déroulant.

 

Ah oui au fait il faut aussi un image pour le bouton de mise à jour  icon/refresh.gif  vous mettez celui que vous voulez sinon PatriceVigier a mis un lien sur le post anglais dont je parle plus haut.

 

Cart.php

Trouver la ligne else if ($operator == 'down') et placer sous cette condition 

elseif ($operator == 'setto') {
	$result2 = Db::getInstance()->getRow('
	SELECT ' . ($id_product_attribute ? 'pa' : 'p') . '.`quantity`, p.`out_of_stock`
		FROM `' . _DB_PREFIX_ . 'product` p
		' . ($id_product_attribute ? 'LEFT JOIN `' . _DB_PREFIX_ . 'product_attribute` pa ON p.`id_product` = pa.`id_product`' : '') . '
		WHERE p.`id_product` = ' . intval($id_product) .
		($id_product_attribute != NULL ? ' AND `id_product_attribute` = ' . intval($id_product_attribute) : ''));

	$result2 = result2 + 0;
	$product_qty = intval($result2['quantity']);
	$new_qty = intval($quantity);
	$qty = intval($quantity);
	if (!Product::isAvailableWhenOutOfStock(intval($result2['out_of_stock'])))
		if (intval($new_qty) > $product_qty)
			return false;
}

Trouvez ensuite ces lignes

/* Delete product from cart */
if ($new_qty <= 0)
	return $this->deleteProduct((int)$id_product, (int)$id_product_attribute, (int)$id_customization);
else if ($new_qty < $minimal_quantity)
	return -1;
else
	Db::getInstance()->execute('
		UPDATE `'._DB_PREFIX_.'cart_product`
		SET `quantity` = `quantity` '.$qty.', `date_add` = NOW()
		WHERE `id_product` = '.(int)$id_product.
		(!empty($id_product_attribute) ? ' AND `id_product_attribute` = '.(int)$id_product_attribute : '').'
		AND `id_cart` = '.(int)$this->id.(Configuration::get('PS_ALLOW_MULTISHIPPING') && $this->isMultiAddressDelivery() ? ' AND `id_address_delivery` = '.(int)$id_address_delivery : '').'
		LIMIT 1'
	);

et remplacez 

SET `quantity` = `quantity` '.$qty.', `date_add` = NOW()

par

SET `quantity` = '.$qty.', `date_add` = NOW()

Bon et bien voilà, c'est la première aide que je place sur ce forum, ouvrons le champagne !  ;)

 

J'espère que ce sera utile à quelqu'un.

 

Voili voilou et à plus dans l'bus (pour la ringardise...c'est fait  :P )

Edited by frieurieud (see edit history)
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...