Vendu par quantité

  • Posts: 457
  • Thank you received: 32
  • Hikamarket Multivendor Hikashop Business
1 month 2 days ago #364552

Bonjour,

je l'avais fait pour un site mais en mode très sale, je voudrais savoir, selon vous quelle est la méthode la plus propre pour que product_min_per_order soit aussi la valeur d'incrémentation, exemple, un produit réglé sur 3 dans product_min_per_order ne pourra etre vendu que par multiples de 3.

J'avais modifié show_quantity et bidouillé ici et là, mais peut etre existe t'il une solution propre ?

Merci d'avance

Please Log in or Create an account to join the conversation.

  • Posts: 83022
  • Thank you received: 13403
  • MODERATOR
1 month 2 days ago #364559

Bonjour,

Bizarre. Il n'y a rien à bidouiller pour cela normalement. Il suffit de changer l'option "input method" du produit en "show select" et HikaShop va remplacer le champ quantité par un dropdown avec comme minimum et comme incrément la valeur de product_min_per_order. Donc cela semble répondre à votre besoin.

Please Log in or Create an account to join the conversation.

  • Posts: 457
  • Thank you received: 32
  • Hikamarket Multivendor Hikashop Business
3 weeks 6 days ago #364639

Bonjour,

merci pour votre réponse, effectivement la solution est en select, et l'expérience utilisateur est donc impactée lors de la saisie de grandes quantités, ce qui sera le cas pour ce site.

Je pensais plutôt à un step d'input number, d'où la modification de show_quantity, le souci c'est que l'input est un type text, et même en changeant pour number avec un step, le bouton ne déclenche pas un submit de validation de form, mais une fonction hikashop, donc même en number avec un step il est possible d'entrer une quantité non autorisée

Last edit: 3 weeks 6 days ago by Minie.

Please Log in or Create an account to join the conversation.

  • Posts: 83022
  • Thank you received: 13403
  • MODERATOR
3 weeks 6 days ago #364640

Donc en effet, dans ce cas, une personnalisation de show_quantity est nécessaire.

Après, concernant le fait d'entrer une valeur non valide dans le champ, vous pouvez très bien rajouter une vérification.
Par défaut, dans votre HTML vous devez avoir quelque chose du genre:

onchange="window.hikashop.checkQuantity(this);"
que vous pourriez changer en :
onchange="if(this.value % 3 != 0) { this.value = this.value - (this.value % 3); } window.hikashop.checkQuantity(this);"
par exemple. Ainsi, cela vérifiera que le nombre renseigné soit bien un multiple de 3.

Last edit: 3 weeks 6 days ago by nicolas.

Please Log in or Create an account to join the conversation.

  • Posts: 457
  • Thank you received: 32
  • Hikamarket Multivendor Hikashop Business
3 weeks 2 days ago #364735

Bonjour Nicolas,

merci pour votre réponse.

J'ai bien fait la modif dans show_quantity, ca marche très bien, et c'est plus propre que le script que j'avait commencé :

// QUANTITY FIELD MIN PER ORDER
$(document).ready(function () {
	// Fonction pour valider et corriger les quantités
	const validateAndCorrectQuantities = () => {
		$("input[data-hk-qty-min]").each(function () {
			const $input = $(this); // Champ actuel
			const minStep = parseFloat($input.data("hk-qty-min")); // Récupérer le step (data-hk-qty-min)
			let value = parseFloat($input.val()) || 0; // Quantité saisie

			// Supprimer tout ancien message d'infobulle
			$input.next(".quantity-tooltip").remove();

			if (value % minStep !== 0) {
				// Calcul de la quantité valide (arrondie à la valeur supérieure)
				const correctedValue = Math.ceil(value / minStep) * minStep;

				// Mettre à jour l'input avec la valeur corrigée
				$input.val(correctedValue);

				// Ajouter une infobulle à côté de l'input
				const message = `
					<div class="quantity-tooltip" style="
						position: absolute;
						background: #fff3f3;
						color: red;
						border: 1px solid red;
						border-radius: 5px;
						padding: 5px 10px;
						font-size: 0.9em;
						z-index: 1000;
						white-space: nowrap;
						box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
						cursor: pointer;
					">
						${value} n'est pas une quantité autorisée. Ce produit est vendu par ${minStep}.
						La quantité a été arrondie à ${correctedValue}.
					</div>
				`;
				$input.after(message);

				// Positionner la tooltip au bon endroit
				const inputPosition = $input.position();
				const inputHeight = $input.outerHeight();
				$input.next(".quantity-tooltip").css({
					top: inputPosition.top + inputHeight + 5 + "px",
					left: inputPosition.left + "px",
				});
			}
		});
	};

	// Événement : Validation et correction lors de la saisie
	$("input[data-hk-qty-min]").on("blur", function () {
		validateAndCorrectQuantities();
	});

	// Événement : Validation et correction lors de clics sur les boutons (+/-)
	$("button").on("click", function () {
		// Vérifie si le clic modifie la quantité
		if ($(this).hasClass("increment") || $(this).hasClass("decrement")) {
			validateAndCorrectQuantities();
		}
	});

	// Événement : Supprimer l'infobulle au clic sur celle-ci
	$(document).on("click", ".quantity-tooltip", function () {
		$(this).remove();
	});
});

J'avais aussi modifié les
<div class="hikashop_product_quantity_change_div_plus_regrouped">
						<a class="hikashop_product_quantity_field_change_plus hikashop_product_quantity_field_change <?php echo $css_button; ?>"
							href="#" data-hk-qty-mod="1"
							onclick="return window.hikashop.updateQuantity(this, '<?php echo $id; ?>');">+</a>
					</div>
					<div class="hikashop_product_quantity_change_div_minus_regrouped">
						<a class="hikashop_product_quantity_field_change_minus hikashop_product_quantity_field_change <?php echo $css_button; ?>"
							href="#" data-hk-qty-mod="-1"
							onclick="return window.hikashop.updateQuantity(this, '<?php echo $id; ?>');">&ndash;</a>
					</div>

en
<div class="hikashop_product_quantity_change_div_plus_regrouped">
						<a class="hikashop_product_quantity_field_change_plus hikashop_product_quantity_field_change <?php echo $css_button; ?>"
							href="#" data-hk-qty-mod="<?php echo $min_quantity; ?>"
							onclick="return window.hikashop.updateQuantity(this, '<?php echo $id; ?>');">+</a>
					</div>
					<div class="hikashop_product_quantity_change_div_minus_regrouped">
						<a class="hikashop_product_quantity_field_change_minus hikashop_product_quantity_field_change <?php echo $css_button; ?>"
							href="#" data-hk-qty-mod="-<?php echo $min_quantity; ?>"
							onclick="return window.hikashop.updateQuantity(this, '<?php echo $id; ?>');">&ndash;</a>
					</div>

ca je le garde

par contre le script que j'avais commencé incluait aussi le panier, j'ai tenté de faire le même type de modif dans layout quantity mais sans succès

Please Log in or Create an account to join the conversation.

  • Posts: 457
  • Thank you received: 32
  • Hikamarket Multivendor Hikashop Business
3 weeks 2 days ago #364740

Je vais plutôt m'orienter sur mon script, car il corrige et informe, et sinon le message est celui de la quantité minimum et non de l'incrémentation

Je dois encore l'améliorer mais ca donne à peu prêt ca

// QUANTITY FIELD MIN PER ORDER
$(document).ready(function () {
	// Fonction pour valider et corriger les quantités
	const validateAndCorrectQuantities = ($input, isCheckout) => {
		const minStep = parseFloat($input.data("hk-qty-min")); // Step minimal
		const maxStep = parseFloat($input.data("hk-qty-max")) || Infinity; // Step maximal (si défini)
		let value = parseFloat($input.val()) || 0; // Quantité saisie

		// Supprimer tout ancien message d'infobulle
		$input.next(".quantity-tooltip").remove();

		// Vérification des conditions de validité
		let isValid = true;
		if (value % minStep !== 0) {
			isValid = false;
			// Corriger la quantité à la valeur supérieure
			value = Math.ceil(value / minStep) * minStep;
		}
		if (value > maxStep) {
			isValid = false;
			value = maxStep; // Limiter à la valeur maximale
		}

		// Appliquer la correction si nécessaire
		if (!isValid) {
			// Mettre à jour l'input avec la valeur corrigée
			$input.val(value);

			// Ajouter une infobulle pour informer l'utilisateur
			const message = `
                <div class="quantity-tooltip">
                    Quantité arrondié à la valeur suppérieure autoriée.<br>Ce produit est vendu par ${minStep}.
                </div>
            `;
			$input.after(message);

			// Positionner l'infobulle au bon endroit
			const inputOffset = $input.offset();
			const inputHeight = $input.outerHeight();
			$input.next(".quantity-tooltip").css({
				top: inputOffset.top + inputHeight + 10 + "px",
				left: inputOffset.left - 10 + "px",
				position: "absolute",
			});
		}

		return isValid;
	};

	// Intercepter et gérer l'événement onchange
	$("input[data-hk-qty-min]").each(function () {
		const $input = $(this);

		// Sauvegarder l'ancien gestionnaire d'événements onchange
		const originalOnChange = $input.attr("onchange");
		$input.data("originalOnChange", originalOnChange);

		// Identifier si on est sur la page panier ou produit
		const isCheckout =
			originalOnChange && originalOnChange.includes("checkout");
		$input.data("isCheckout", isCheckout);

		// Supprimer l'attribut onchange
		$input.removeAttr("onchange");
	});

	// Délégation d'événements pour l'événement change
	$(document).on("change", "input[data-hk-qty-min]", function (event) {
		event.preventDefault(); // Empêcher l'exécution immédiate
		const $input = $(this);

		// Récupérer les données stockées
		const originalOnChange = $input.data("originalOnChange");
		const isCheckout = $input.data("isCheckout");

		// Valider et corriger la quantité
		const isValid = validateAndCorrectQuantities($input, isCheckout);

		if (isValid) {
			// Quantité valide : exécuter le script onchange original
			if (originalOnChange) {
				eval(originalOnChange);
			}
		} else if (isCheckout) {
			// Quantité corrigée sur la page panier : mettre à jour avec la nouvelle valeur
			if (
				window.hikashop &&
				typeof window.hikashop.checkQuantity === "function"
			) {
				window.hikashop.checkQuantity($input[0]); // Appeler directement la fonction
			}
			if (window.checkout && typeof window.checkout.submitCart === "function") {
				window.checkout.submitCart(1, 0); // Mettre à jour le panier après correction
			}
		} else {
			// Quantité corrigée sur la page produit : ne pas valider
			console.log(
				"Quantité corrigée sur la page produit. Pas de mise au panier automatique."
			);
		}
	});

	// Délégation d'événements pour l'événement blur
	$(document).on("blur", "input[data-hk-qty-min]", function () {
		const $input = $(this);
		const isCheckout = $input.data("isCheckout");
		validateAndCorrectQuantities($input, isCheckout);
	});

	// Délégation d'événements pour l'appui sur la touche Entrée
	$(document).on("keypress", "input[data-hk-qty-min]", function (event) {
		if (event.which === 13) {
			// 13 correspond à la touche Entrée
			event.preventDefault(); // Empêche l'action par défaut (soumission de formulaire)
			const $input = $(this);
			const isCheckout = $input.data("isCheckout");
			validateAndCorrectQuantities($input, isCheckout);
		}
	});

	// Événement : Supprimer l'infobulle au clic sur celle-ci
	$(document).on("click", ".quantity-tooltip", function () {
		$(this).remove();
	});
});

The following user(s) said Thank You: nicolas

Please Log in or Create an account to join the conversation.

Time to create page: 0.059 seconds
Powered by Kunena Forum