🎨 Design & ThèmesIntermédiaire PS 1.6 PS 1.7 PS 8.x

Ajouter des boutons + et - pour la quantité sur la fiche produit PrestaShop

Intégrez des boutons d'incrémentation +/- à côté du champ quantité sur vos fiches produits PrestaShop. Guide complet avec code pour PS 1.7 et 8.x.

En bref : PrestaShop 1.7 et 8.x intègrent nativement des boutons +/- via TouchSpin dans le thème Classic. Pour les thèmes personnalisés, une implémentation en Vanilla JS avec des boutons HTML accessibles, un dispatch d'événement change et le respect de la quantité minimale suffit à recréer cette fonctionnalité.

Publié le 21 mars 2026 6 min de lecture Alexandre Carette

Pourquoi ajouter des boutons +/- sur le sélecteur de quantité

Le champ de quantité par défaut sur une fiche produit PrestaShop est un simple . Sur mobile comme sur desktop, ce champ brut pose plusieurs problèmes d'ergonomie : les petites flèches natives du navigateur sont difficiles à cliquer, l'expérience tactile est médiocre, et l'aspect visuel s'intègre rarement au design du thème.

Ajouter des boutons + et explicites améliore significativement le taux de conversion. Les études UX montrent qu'un sélecteur de quantité bien conçu réduit les erreurs de saisie et encourage les commandes multi-articles.

Comportement natif selon les versions de PrestaShop

PrestaShop 1.5 et 1.6

Sur PrestaShop 1.5, les boutons d'incrémentation étaient intégrés nativement dans le thème par défaut. Le template product.tpl incluait déjà des éléments .qty_up et .qty_down avec des images cliquables. Si votre thème personnalisé ne les affiche plus, c'est probablement parce que le template a été modifié ou que le CSS les masque.

Sur PrestaShop 1.6, le thème Bootstrap par défaut a conservé ce mécanisme, mais avec un rendu différent utilisant des icônes Font Awesome.

PrestaShop 1.7 et 8.x

À partir de PrestaShop 1.7, le thème Classic inclut nativement un composant TouchSpin (via Bootstrap TouchSpin) qui gère les boutons +/−. Le sélecteur de quantité est géré dans le fichier :


themes/classic/templates/catalog/product.tpl

Le composant est initialisé automatiquement par le JavaScript du thème. Si ces boutons n'apparaissent pas, le problème vient généralement du thème personnalisé qui n'inclut pas les dépendances nécessaires.

Solution pour PrestaShop 1.7 / 8.x (thème Classic et dérivés)

Vérifier que le composant natif fonctionne

Dans le thème Classic, le sélecteur de quantité se trouve dans :


themes/classic/templates/catalog/_partials/product-add-to-cart.tpl

Le markup natif ressemble à ceci :


<div class="qty">
  <input
    type="number"
    name="qty"
    id="quantity_wanted"
    inputmode="numeric"
    pattern="[0-9]*"
    value="{$product.minimal_quantity}"
    class="input-group"
    min="{$product.minimal_quantity}"
    aria-label="{l s='Quantity' d='Shop.Theme.Actions'}"
  />
</div>

Le plugin jQuery Bootstrap TouchSpin transforme automatiquement cet input en un composant avec boutons. Si ça ne fonctionne pas, vérifiez que le fichier JavaScript du thème charge bien la bibliothèque.

Implémentation manuelle (thème custom sans TouchSpin)

Si votre thème personnalisé ne dispose pas de TouchSpin, voici une implémentation propre et moderne :

#### 1. Modifier le template Smarty

Créez ou éditez le fichier dans votre thème enfant :


themes/votre-theme/templates/catalog/_partials/product-add-to-cart.tpl

<div class="product-quantity clearfix">
  <div class="qty-wrapper d-flex align-items-center">
    <button
      type="button"
      class="btn btn-touchspin qty-btn qty-down"
      data-action="decrease"
      aria-label="{l s='Decrease quantity' d='Shop.Theme.Actions'}"
    >
      <span>−</span>
    </button>

    <input
      type="number"
      name="qty"
      id="quantity_wanted"
      inputmode="numeric"
      pattern="[0-9]*"
      value="{$product.minimal_quantity}"
      class="input-qty"
      min="{$product.minimal_quantity}"
      aria-label="{l s='Quantity' d='Shop.Theme.Actions'}"
    />

    <button
      type="button"
      class="btn btn-touchspin qty-btn qty-up"
      data-action="increase"
      aria-label="{l s='Increase quantity' d='Shop.Theme.Actions'}"
    >
      <span>+</span>
    </button>
  </div>
</div>

#### 2. JavaScript propre et compatible

Ajoutez ce script dans le fichier custom.js de votre thème ou dans un bloc {literal} en bas du template :


document.addEventListener('DOMContentLoaded', function () {
  const qtyInput = document.getElementById('quantity_wanted');
  if (!qtyInput) return;

  const minQty = parseInt(qtyInput.getAttribute('min'), 10) || 1;

  document.querySelectorAll('.qty-btn').forEach(function (btn) {
    btn.addEventListener('click', function () {
      let currentVal = parseInt(qtyInput.value, 10);
      if (isNaN(currentVal)) currentVal = minQty;

      if (this.dataset.action === 'increase') {
        qtyInput.value = currentVal + 1;
      } else if (this.dataset.action === 'decrease') {
        if (currentVal > minQty) {
          qtyInput.value = currentVal - 1;
        }
      }

      // Déclencher l'événement change pour que PrestaShop
      // mette à jour le prix et la disponibilité
      qtyInput.dispatchEvent(new Event('change', { bubbles: true }));
    });
  });
});

Point crucial : le dispatchEvent sur l'événement change est indispensable. Sans cela, PrestaShop ne recalcule pas le prix unitaire en fonction des remises par quantité ni ne vérifie le stock disponible.

#### 3. Styles CSS

Ajoutez ces styles dans le fichier custom.css de votre thème :


.qty-wrapper {
  display: inline-flex;
  align-items: center;
  border: 1px solid #e0e0e0;
  border-radius: 4px;
  overflow: hidden;
}

.qty-btn {
  width: 40px;
  height: 40px;
  border: none;
  background-color: #f5f5f5;
  font-size: 1.2rem;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: background-color 0.2s;
  user-select: none;
}

.qty-btn:hover {
  background-color: #e0e0e0;
}

.qty-btn:active {
  background-color: #d0d0d0;
}

.input-qty {
  width: 50px;
  height: 40px;
  text-align: center;
  border: none;
  border-left: 1px solid #e0e0e0;
  border-right: 1px solid #e0e0e0;
  font-size: 1rem;
  -moz-appearance: textfield;
}

.input-qty::-webkit-outer-spin-button,
.input-qty::-webkit-inner-spin-button {
  -webkit-appearance: none;
  margin: 0;
}

La suppression des flèches natives via -webkit-appearance: none évite le doublon visuel entre les boutons natifs du navigateur et vos boutons personnalisés.

Gestion de la quantité minimale

PrestaShop permet de définir une quantité minimale d'achat par produit (champ minimal_quantity dans la fiche produit). Votre implémentation doit impérativement respecter cette valeur :

  • La valeur initiale de l'input doit être `minimal_quantity` (pas 1)
  • Le bouton − ne doit jamais descendre en dessous de cette valeur
  • L'attribut `min` de l'input HTML doit refléter cette valeur

Dans le code JavaScript ci-dessus, la variable minQty gère cela automatiquement en lisant l'attribut min de l'input.

Mise à jour dynamique du prix

Sur PrestaShop 1.7+ et 8.x, le prix se met à jour dynamiquement grâce au composant JavaScript prestashop.on('updatedProduct'). Si vous avez des remises par paliers de quantité, le simple fait de déclencher l'événement change sur l'input suffit à ce que le core recalcule et affiche le bon prix.

Si vous souhaitez afficher le prix total (prix unitaire × quantité) en temps réel, ajoutez un élément dans votre template :


<p class="total-price" id="total_price_display"></p>

Puis écoutez les changements :


if (typeof prestashop !== 'undefined') {
  prestashop.on('updatedProduct', function (event) {
    const qty = parseInt(document.getElementById('quantity_wanted').value, 10);
    const unitPrice = parseFloat(event.product_prices?.price_amount || 0);
    const totalEl = document.getElementById('total_price_display');
    if (totalEl && qty && unitPrice) {
      totalEl.textContent = 'Total : ' + (unitPrice * qty).toFixed(2) + ' €';
    }
  });
}

Accessibilité (a11y)

Pour une implémentation conforme aux standards d'accessibilité :

  • Ajoutez des `aria-label` explicites sur chaque bouton ("Diminuer la quantité", "Augmenter la quantité")
  • Utilisez des éléments `
  • Assurez-vous que les boutons sont navigables au clavier (focus visible)
  • Le champ input doit avoir `inputmode="numeric"` pour afficher le clavier numérique sur mobile

Erreurs fréquentes à éviter

Ne pas déclencher l'événement `change`

C'est l'erreur la plus courante. Modifier input.value en JavaScript ne déclenche pas automatiquement l'événement change. Sans dispatchEvent, PrestaShop ne sait pas que la quantité a changé, le prix ne se met pas à jour, et le stock n'est pas revérifié.

Utiliser jQuery `.val()` sans `.trigger('change')`

Si vous utilisez jQuery, la même règle s'applique :


// ❌ Mauvais
$('#quantity_wanted').val(newQty);

// ✅ Correct
$('#quantity_wanted').val(newQty).trigger('change');

Oublier la validation de la saisie

Toujours vérifier que la valeur est un entier valide avec parseInt() et gérer le cas NaN. Un utilisateur peut vider le champ manuellement, et votre code doit remettre la quantité minimale dans ce cas.

Ignorer les produits virtuels

Les produits virtuels (fichiers téléchargeables) n'ont généralement pas de sélecteur de quantité visible. Votre code doit respecter la condition {if $product.add_to_cart_url} pour ne pas afficher les boutons inutilement.

#quantité produit #fiche produit #UX e-commerce #template Smarty #JavaScript #panier

Questions fréquentes

Tout ce que vous devez savoir sur ce sujet.

Un projet PrestaShop ?

Discutons-en directement.

★★★★★

193 projets livrés

Gratuit & sans engagement — réponse sous 24h

Alexandre Carette

Alexandre Carette

Expert PrestaShop & Architecture E-commerce

Développeur PrestaShop depuis 2014, 193 projets livrés. Je conçois des architectures headless Nuxt + PrestaShop et des outils d'automatisation IA pour les e-commerçants.