EricDota Posted March 12, 2021 Share Posted March 12, 2021 Bonjour, Je souhaite établir un calcul simple sur le front en utilisant une donnée du produit que je souhaite multiplier par la quantité que l'utilisateur sélectionne sur la page produit. Cela dans le but d'afficher une information comme : "Soit 8.4 m²" à côté de l'input de quantité. Cependant, je viens de remarquer que la donnée {$product.quantity_wanted} est gérée dynamiquement en JS, il m'est impossible de mettre à jour mon calcul quand l'utilisateur change la quantité. Comment puis-je résoudre ce problème ? Merci Link to comment Share on other sites More sharing options...
Remy FRK Corp Posted March 14, 2021 Share Posted March 14, 2021 (edited) Bonjour. {$product.quantity_wanted} se comporte de façon "dynamique" lorsqu'elle est dans product-details.tpl par exemple (elle se fait embarquée par l'ajax qui agit sur ce .tpl niveau id="product-details) En remaniant un peu tous cela niveau de vos .tpl (et surement un peu de css aussi), il y'a sans doute moyen de faire ce que vous voulez. ... Sinon si vous tenez absolument à faire votre manip de manière clean vous pourriez envisager d'en faire un module...mais là, il faut les compétences requises. ... Solution intermédiaire (mais fastidieuse) probable que d'autres aient mieux à proposer, Un override du ProductControler.php (voir du coté de : public function displayAjaxRefresh() et s'inspirer de : 'product_details' => $this->render('catalog/_partials/product-details'),) en suite s'inspirer de ce qu'on trouve dans core.js (Sans le modifier car c'est un fichier webpack >> ou alors modif des fichiers JS qui composent core.js (qui doivent êtres dans un répertoire _dev),puis jouer du NPM pour recompiler la chose) Donc plutôt passé par le custom.js s'inspirer de fonctions style : var s = null, u = null; function l(e) { void 0 === e && (e = "An error occurred while processing your request"), function (e, t) { var n = (0, r.default)('<div class="alert alert-danger ajax-error" role="alert">'.concat(t, "</div>")); e.replaceWith(n) }((0, r.default)(".quickview #product-availability, .page-product:not(.modal-open) .row #product-availability, .page-product:not(.modal-open) .product-container #product-availability"), e) } function c(e, t, n) { var a = (0, r.default)(".product-actions"), c = a.find("#quantity_wanted"), f = a.find("form:first").serialize(), p = (0, i.psGetRequestParameter)("preview"); if (p = null !== p ? "&preview=" + p : "", null !== n) { if (!e || "keyup" !== e.type || c.val() !== c.data("old-value")) { c.data("old-value", c.val()), u && clearTimeout(u); var h = 30; "updatedProductQuantity" === t && (h = 750), u = setTimeout(function () { "" !== f && (s = r.default.ajax({ url: n + (-1 === n.indexOf("?") ? "?" : "&") + f + p, method: "POST", data: { quickview: (0, r.default)(".modal.quickview.in").length, ajax: 1, action: "refresh", quantity_wanted: "updatedProductCombination" === t ? c.attr("min") : c.val() }, dataType: "json", beforeSend: function () { null !== s && s.abort() }, error: function (e, t, n) { "abort" !== t && 0 === (0, r.default)("section#main > .ajax-error").length && l() }, success: function (e, n, i) { var a = (0, r.default)("<div>").append(e.product_cover_thumbnails); (0, r.default)(".quickview .images-container, .page-product:not(.modal-open) .row .images-container, .page-product:not(.modal-open) .product-container .images-container").html() !== a.find(".quickview .images-container, .page-product:not(.modal-open) .row .images-container, .page-product:not(.modal-open) .product-container .images-container").html() && (0, r.default)(".quickview .images-container, .page-product:not(.modal-open) .row .images-container, .page-product:not(.modal-open) .product-container .images-container").replaceWith(e.product_cover_thumbnails), (0, r.default)(".quickview .product-prices, .page-product:not(.modal-open) .row .product-prices, .page-product:not(.modal-open) .product-container .product-prices").first().replaceWith(e.product_prices), (0, r.default)(".quickview .product-customization, .page-product:not(.modal-open) .row .product-customization, .page-product:not(.modal-open) .product-container .product-customization").first().replaceWith(e.product_customization), (0, r.default)(".quickview .product-variants, .page-product:not(.modal-open) .row .product-variants, .page-product:not(.modal-open) .product-container .product-variants").first().replaceWith(e.product_variants), (0, r.default)(".quickview .product-discounts, .page-product:not(.modal-open) .row .product-discounts, .page-product:not(.modal-open) .product-container .product-discounts").first().replaceWith(e.product_discounts), (0, r.default)(".quickview .product-additional-info, .page-product:not(.modal-open) .row .product-additional-info, .page-product:not(.modal-open) .product-container .product-additional-info").first().replaceWith(e.product_additional_info), (0, r.default)(".quickview #product-details, #product-details").replaceWith(e.product_details), (0, r.default)(".quickview .product-flags, .page-product:not(.modal-open) .row .product-flags, .page-product:not(.modal-open) .product-container .product-flags").first().replaceWith(e.product_flags), function (e) { var t = null; (0, r.default)(e.product_add_to_cart).each(function (e, n) { if ((0, r.default)(n).hasClass("product-add-to-cart")) return t = (0, r.default)(n), !1 }), null === t && l(); var n = (0, r.default)(".product-add-to-cart"); d({ $addToCartSnippet: t, $targetParent: n, targetSelector: ".add" }), d({ $addToCartSnippet: t, $targetParent: n, targetSelector: "#product-availability" }), d({ $addToCartSnippet: t, $targetParent: n, targetSelector: ".product-minimal-quantity" }) }(e); var s = parseInt(e.product_minimal_quantity, 10); isNaN(s) || "updatedProductQuantity" === t || (c.attr("min", s), c.val(s)), o.default.emit("updatedProduct", e) }, complete: function (e, t) { s = null, u = null } })) }.bind(s, u), h) } } else l() } Pour l'exemple je me suis amusé avec un: (0, r.default)(".product-jetest").replaceWith(e.product_jetest) Du coup une div class product-jetest avec du {$product.quantity_wanted} dedans, située dans un nouveau fichier.tpl que j'ai appelé product-jetest.tpl et placé dans catalog/_partials/ Rappel : dans l'override du product controller j'ai mis un: 'product_jetest' => $this->render('catalog/_partials/product-jetest') Donc product-jetest.tpl (dans lequel à priori il faudrait que vous fassiez vos opérations de calcul de mètres carrés) que j'ai fini par appeler par include dans mon fichier product.tpl j'ai bien terminé avec un double affichage dynamique et calculable" de ma valeure input de qté avec {$product.quantity_wanted} que je peux mettre ou ca me chante dans la fiche produit (je sais pas si j'ai raté une marche mais j'ai pas eut d'erreur ni d'effets de bord) Mais franchement je trouve que je me suis pris la tète pour pas grand chose (surtout que je suis pas à l’abri qu'un VRAIS dev passe par là et lâche une solution qui tient sur 2 lignes....) Edited March 16, 2021 by Remy FRK Corp (see edit history) Link to comment Share on other sites More sharing options...
AlexandreFR Posted February 17, 2022 Share Posted February 17, 2022 Bonjour, Je n'arrive pas à comprendre comment fonctionne le code. Dans custom.js j'ai simplement changé le product-actions. function l(e) { void 0 === e && (e = "An error occurred while processing your request"), function (e, t) { var n = (0, r.default)('<div class="alert alert-danger ajax-error" role="alert">'.concat(t, "</div>")); e.replaceWith(n) }((0, r.default)(".quickview #product-availability, .page-product:not(.modal-open) .row #product-availability, .page-product:not(.modal-open) .product-container #product-availability"), e) } function c(e, t, n) { var a = (0, r.default)(".product-jetest"), c = a.find("#quantity_wanted"), f = a.find("form:first").serialize(), p = (0, i.psGetRequestParameter)("preview"); if (p = null !== p ? "&preview=" + p : "", null !== n) { if (!e || "keyup" !== e.type || c.val() !== c.data("old-value")) { c.data("old-value", c.val()), u && clearTimeout(u); var h = 30; "updatedProductQuantity" === t && (h = 750), u = setTimeout(function () { "" !== f && (s = r.default.ajax({ url: n + (-1 === n.indexOf("?") ? "?" : "&") + f + p, method: "POST", data: { quickview: (0, r.default)(".modal.quickview.in").length, ajax: 1, action: "refresh", quantity_wanted: "updatedProductCombination" === t ? c.attr("min") : c.val() }, dataType: "json", beforeSend: function () { null !== s && s.abort() }, error: function (e, t, n) { "abort" !== t && 0 === (0, r.default)("section#main > .ajax-error").length && l() }, success: function (e, n, i) { var a = (0, r.default)("<div>").append(e.product_cover_thumbnails); (0, r.default)(".quickview .images-container, .page-product:not(.modal-open) .row .images-container, .page-product:not(.modal-open) .product-container .images-container").html() !== a.find(".quickview .images-container, .page-product:not(.modal-open) .row .images-container, .page-product:not(.modal-open) .product-container .images-container").html() && (0, r.default)(".quickview .images-container, .page-product:not(.modal-open) .row .images-container, .page-product:not(.modal-open) .product-container .images-container").replaceWith(e.product_cover_thumbnails), (0, r.default)(".quickview .product-prices, .page-product:not(.modal-open) .row .product-prices, .page-product:not(.modal-open) .product-container .product-prices").first().replaceWith(e.product_prices), (0, r.default)(".quickview .product-customization, .page-product:not(.modal-open) .row .product-customization, .page-product:not(.modal-open) .product-container .product-customization").first().replaceWith(e.product_customization), (0, r.default)(".quickview .product-variants, .page-product:not(.modal-open) .row .product-variants, .page-product:not(.modal-open) .product-container .product-variants").first().replaceWith(e.product_variants), (0, r.default)(".quickview .product-discounts, .page-product:not(.modal-open) .row .product-discounts, .page-product:not(.modal-open) .product-container .product-discounts").first().replaceWith(e.product_discounts), (0, r.default)(".quickview .product-additional-info, .page-product:not(.modal-open) .row .product-additional-info, .page-product:not(.modal-open) .product-container .product-additional-info").first().replaceWith(e.product_additional_info), (0, r.default)(".quickview #product-details, #product-details").replaceWith(e.product_details), (0, r.default)(".quickview .product-flags, .page-product:not(.modal-open) .row .product-flags, .page-product:not(.modal-open) .product-container .product-flags").first().replaceWith(e.product_flags), function (e) { var t = null; (0, r.default)(e.product_add_to_cart).each(function (e, n) { if ((0, r.default)(n).hasClass("product-add-to-cart")) return t = (0, r.default)(n), !1 }), null === t && l(); var n = (0, r.default)(".product-add-to-cart"); d({ $addToCartSnippet: t, $targetParent: n, targetSelector: ".add" }), d({ $addToCartSnippet: t, $targetParent: n, targetSelector: "#product-availability" }), d({ $addToCartSnippet: t, $targetParent: n, targetSelector: ".product-minimal-quantity" }) }(e); var s = parseInt(e.product_minimal_quantity, 10); isNaN(s) || "updatedProductQuantity" === t || (c.attr("min", s), c.val(s)), o.default.emit("updatedProduct", e) }, complete: function (e, t) { s = null, u = null } })) }.bind(s, u), h) } } else l() } Et dans product-jetest.tpl, ça {block name='essai'} <div class="product-jetest"> <label>{l e='product_jetest' t='.product-jetest'}</label> <span>{$product.quantity_wanted}</span> </div> {/block} Merci, pour le code, on ne trouve rien sur le sujet ! Link to comment Share on other sites More sharing options...
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now