{"product_id":"maillot-bresil-2026-2027-copie-copie-copie-copie-copie-copie-copie-copie-copie-copie","title":"Maillot Japon 2026\/2027","description":"\u003c!-- BLOC FLOCAGE PERSONNALISÉ --\u003e\n\u003cdiv class=\"custom-flocage-wrapper\" style=\"display:none;\"\u003e\n\n  \u003cdiv class=\"maillot-info\"\u003e\n    \u003cp class=\"flocage-title\"\u003e\n      🔥 \u003cstrong\u003eFlocage personnalisé disponible pour seulement 5€\u003c\/strong\u003e 🔥\n    \u003c\/p\u003e\n    \u003cp\u003e⚽ \u003cstrong\u003eQualité Joueur – Maillots Premium\u003c\/strong\u003e\u003c\/p\u003e\n    \u003cp\u003eNos maillots sont conçus en qualité joueur, identique à celle portée par les professionnels sur le terrain.\u003c\/p\u003e\n  \u003c\/div\u003e\n\n  \u003cdiv id=\"flocage-box\" style=\"display:none;\"\u003e\n    \u003clabel\u003eNom du joueur\u003c\/label\u003e\n    \u003cinput type=\"text\" id=\"flocage-nom\" placeholder=\"Ex : Fiére\"\u003e\n    \u003clabel\u003eNuméro\u003c\/label\u003e\n    \u003cinput type=\"text\" id=\"flocage-numero\" placeholder=\"Ex : 2\"\u003e\n    \u003clabel\u003eInscription sous le numéro\u003c\/label\u003e\n    \u003cinput type=\"text\" id=\"flocage-inscription\" placeholder=\"Ex :Malade\"\u003e\n  \u003c\/div\u003e\n\n\u003c\/div\u003e\n\n\u003cstyle\u003e\n.custom-flocage-wrapper { margin-top: 15px; margin-bottom: 15px; }\n.maillot-info { margin-bottom: 18px; font-size: 14px; line-height: 1.7; color: #000; }\n.flocage-title { color: #ff1493; font-size: 16px; font-weight: 700; margin-bottom: 12px; }\n#flocage-box { margin-top: 15px; }\n#flocage-box label { display: block; margin-top: 12px; margin-bottom: 5px; font-weight: 600; color: #000; }\n#flocage-box input {\n  width: 100%; padding: 12px; border: 1px solid #dcdcdc;\n  border-radius: 8px; font-size: 14px; outline: none;\n  transition: 0.2s; box-sizing: border-box;\n}\n#flocage-box input:focus { border-color: #ff1493; }\n#flocage-box input:disabled {\n  background-color: #f5f5f5;\n  cursor: not-allowed;\n  color: #aaa;\n}\n\u003c\/style\u003e\n\n\u003cscript\u003e\n(function () {\n\n  var MAX_WAIT = 8000;\n  var POLL_INTERVAL = 200;\n  var elapsed = 0;\n\n  function isFlocageSelected() {\n    var checked = document.querySelectorAll('select option:checked, input[type=\"radio\"]:checked');\n    for (var i = 0; i \u003c checked.length; i++) {\n      var v = checked[i].value.toLowerCase();\n      if (\n        (v.includes(\"flocage\") || v.includes(\"personnalis\")) \u0026\u0026\n        !v.includes(\"sans\")\n      ) return true;\n    }\n    return false;\n  }\n\n  function getFlocageProperties() {\n    var nom = (document.getElementById(\"flocage-nom\") || {}).value || \"\";\n    var num = (document.getElementById(\"flocage-numero\") || {}).value || \"\";\n    var ins = (document.getElementById(\"flocage-inscription\") || {}).value || \"\";\n    var props = {};\n    if (nom.trim()) props[\"Nom du joueur\"] = nom.trim();\n    if (num.trim()) props[\"Numéro\"] = num.trim();\n    if (ins.trim()) props[\"Inscription sous le numéro\"] = ins.trim();\n    return props;\n  }\n\n  function getVariantId() {\n    var input = document.querySelector('input[name=\"id\"]');\n    if (input \u0026\u0026 input.value) return input.value;\n    var urlParams = new URLSearchParams(window.location.search);\n    if (urlParams.get(\"variant\")) return urlParams.get(\"variant\");\n    if (window.ShopifyAnalytics \u0026\u0026 window.ShopifyAnalytics.meta \u0026\u0026 window.ShopifyAnalytics.meta.selectedVariantId) {\n      return window.ShopifyAnalytics.meta.selectedVariantId;\n    }\n    return null;\n  }\n\n  function getQuantity() {\n    var q = document.querySelector('input[name=\"quantity\"]');\n    return q ? (parseInt(q.value) || 1) : 1;\n  }\n\n  function positionFlocageBlock() {\n    var wrapper = document.querySelector(\".custom-flocage-wrapper\");\n    if (!wrapper) return false;\n\n    var addBtn =\n      document.querySelector('button[name=\"add\"]') ||\n      document.querySelector(\".product-form__submit\") ||\n      document.querySelector('product-form button[type=\"submit\"]') ||\n      document.querySelector('form[action=\"\/cart\/add\"] button[type=\"submit\"]');\n\n    if (!addBtn) return false;\n\n    var btnContainer = addBtn.closest(\".product-form__buttons\") ||\n                       addBtn.closest(\".shopify-payment-button\") ||\n                       addBtn.parentElement;\n\n    if (btnContainer \u0026\u0026 !wrapper._positioned) {\n      btnContainer.insertAdjacentElement(\"beforebegin\", wrapper);\n      wrapper.style.display = \"block\";\n      wrapper._positioned = true;\n    }\n\n    return true;\n  }\n\n  function addToCartWithProperties(variantId, quantity, properties, originalBtn) {\n    if (originalBtn) {\n      originalBtn.disabled = true;\n      originalBtn._originalText = originalBtn.innerText;\n      originalBtn.innerText = \"Ajout en cours...\";\n    }\n\n    fetch(\"\/cart\/add.js\", {\n      method: \"POST\",\n      headers: { \"Content-Type\": \"application\/json\" },\n      body: JSON.stringify({ id: variantId, quantity: quantity, properties: properties })\n    })\n    .then(function (res) { return res.json(); })\n    .then(function (item) {\n      if (item \u0026\u0026 item.key) {\n        return fetch(\"\/cart\/change.js\", {\n          method: \"POST\",\n          headers: { \"Content-Type\": \"application\/json\" },\n          body: JSON.stringify({ id: item.key, quantity: quantity, properties: properties })\n        });\n      }\n    })\n    .then(function () {\n      if (originalBtn) {\n        originalBtn.disabled = false;\n        originalBtn.innerText = originalBtn._originalText || \"Ajouter au panier\";\n      }\n      [\"cart:refresh\", \"cart:updated\", \"theme:cart:open\", \"kaching:refresh\"].forEach(function(ev) {\n        document.dispatchEvent(new CustomEvent(ev));\n        window.dispatchEvent(new CustomEvent(ev));\n      });\n      setTimeout(function () {\n        var kachingOpen =\n          document.querySelector(\"[data-kaching-cart-open]\") ||\n          document.querySelector(\".kaching-cart__toggle\") ||\n          document.querySelector(\"[data-cart-open]\");\n        if (kachingOpen) kachingOpen.click();\n        if (!document.querySelector(\".kaching-cart\")) {\n          window.location.href = \"\/cart\";\n        }\n      }, 400);\n    })\n    .catch(function (err) {\n      console.error(\"[Flocage] Erreur:\", err);\n      if (originalBtn) {\n        originalBtn.disabled = false;\n        originalBtn.innerText = originalBtn._originalText || \"Ajouter au panier\";\n      }\n      alert(\"Une erreur est survenue, veuillez réessayer.\");\n    });\n  }\n\n  function hookButton(btn) {\n    if (btn._flocageHooked) return;\n    btn._flocageHooked = true;\n\n    btn.addEventListener(\"click\", function (e) {\n      if (!isFlocageSelected()) return;\n\n      e.preventDefault();\n      e.stopImmediatePropagation();\n      e.stopPropagation();\n\n      var variantId = getVariantId();\n      if (!variantId) { console.warn(\"[Flocage] Variant ID introuvable\"); return; }\n\n      addToCartWithProperties(variantId, getQuantity(), getFlocageProperties(), btn);\n    }, true);\n  }\n\n  function findAndHookButton() {\n    var btn =\n      document.querySelector('button[name=\"add\"]') ||\n      document.querySelector(\".product-form__submit\") ||\n      document.querySelector('product-form button[type=\"submit\"]') ||\n      document.querySelector('form[action=\"\/cart\/add\"] button[type=\"submit\"]');\n    if (btn) { hookButton(btn); return true; }\n    return false;\n  }\n\n  function checkFlocageVisibility() {\n    var box = document.getElementById(\"flocage-box\");\n    if (!box) return;\n    var selected = isFlocageSelected();\n    box.style.display = selected ? \"block\" : \"none\";\n    box.querySelectorAll(\"input\").forEach(function(i) {\n      i.disabled = !selected;\n      if (!selected) i.value = \"\";\n    });\n  }\n\n  var pollTimer = setInterval(function () {\n    elapsed += POLL_INTERVAL;\n    var positioned = positionFlocageBlock();\n    var hooked = findAndHookButton();\n    if ((positioned \u0026\u0026 hooked) || elapsed \u003e= MAX_WAIT) clearInterval(pollTimer);\n  }, POLL_INTERVAL);\n\n  var observer = new MutationObserver(function () {\n    positionFlocageBlock();\n    findAndHookButton();\n    checkFlocageVisibility();\n  });\n  observer.observe(document.body, { childList: true, subtree: true });\n\n  document.addEventListener(\"change\", checkFlocageVisibility);\n  checkFlocageVisibility();\n\n})();\n\u003c\/script\u003e","brand":"My Store 8","offers":[{"title":"M \/ Flocage","offer_id":57345680212345,"sku":null,"price":29.99,"currency_code":"EUR","in_stock":true},{"title":"M \/ Sans Flocage","offer_id":57345680245113,"sku":null,"price":24.99,"currency_code":"EUR","in_stock":true},{"title":"L \/ Flocage","offer_id":57345680277881,"sku":null,"price":29.99,"currency_code":"EUR","in_stock":true},{"title":"L \/ Sans Flocage","offer_id":57345680310649,"sku":null,"price":24.99,"currency_code":"EUR","in_stock":true},{"title":"XL \/ Flocage","offer_id":57345680343417,"sku":null,"price":29.99,"currency_code":"EUR","in_stock":true},{"title":"XL \/ Sans Flocage","offer_id":57345680376185,"sku":null,"price":24.99,"currency_code":"EUR","in_stock":true},{"title":"2XL \/ Flocage","offer_id":57345680408953,"sku":null,"price":29.99,"currency_code":"EUR","in_stock":true},{"title":"2XL \/ Sans Flocage","offer_id":57345680441721,"sku":null,"price":24.99,"currency_code":"EUR","in_stock":true}],"thumbnail_url":"\/\/cdn.shopify.com\/s\/files\/1\/1002\/3354\/4057\/files\/bd30353e-cb6c-4307-b0a1-8ca8a278dafd.jpg?v=1780071549","url":"https:\/\/lafabriquedumaillot.com\/products\/maillot-bresil-2026-2027-copie-copie-copie-copie-copie-copie-copie-copie-copie-copie","provider":"Lafabriquedumaillot","version":"1.0","type":"link"}