custom/plugins/dkcProductoptions/src/Resources/views/storefront/page/product-detail/index.html.twig line 1

Open in your IDE?
  1. {% sw_extends '@Storefront/storefront/page/product-detail/index.html.twig' %}
  2. {% block page_product_detail_content %}
  3.     {{ parent() }}
  4.     {% if page.product.extensions.dkcProductOptions is defined and page.product.extensions.dkcProductOptions|length > 0 %}
  5.         <script>
  6.             document.addEventListener('DOMContentLoaded', function() {
  7.                 var addToCartForm = document.querySelector('form[action*="checkout/line-item/add"]');
  8.                 if (!addToCartForm) return;
  9.                 // === Live-Preisanzeige ===
  10.                 function parsePriceDE(text) {
  11.                     if (!text) return 0;
  12.                     var clean = text.replace(/[^\d,.\-]/g, '');
  13.                     if (!clean) return 0;
  14.                     if (clean.indexOf(',') !== -1) {
  15.                         var parts = clean.split(',');
  16.                         var intPart = parts[0].replace(/\./g, '');
  17.                         var decPart = parts[1] || '0';
  18.                         return parseFloat(intPart + '.' + decPart) || 0;
  19.                     }
  20.                     var lastDot = clean.lastIndexOf('.');
  21.                     if (lastDot !== -1 && clean.length - lastDot === 3) {
  22.                         var beforeDot = clean.substring(0, lastDot).replace(/\./g, '');
  23.                         return parseFloat(beforeDot + '.' + clean.substring(lastDot + 1)) || 0;
  24.                     }
  25.                     return parseFloat(clean.replace(/\./g, '')) || 0;
  26.                 }
  27.                 function formatCurrency(value) {
  28.                     return value.toLocaleString('de-DE', { minimumFractionDigits: 2, maximumFractionDigits: 2 });
  29.                 }
  30.                 var priceElement = document.querySelector('.product-detail-price');
  31.                 var taxContainer = document.querySelector('.product-detail-tax-container');
  32.                 if (!taxContainer) taxContainer = document.querySelector('.product-detail-tax');
  33.                 var baseDisplayPrice = 0;
  34.                 if (priceElement) {
  35.                     baseDisplayPrice = parsePriceDE(priceElement.textContent);
  36.                 }
  37.                 var taxRate = 19;
  38.                 var displayIsNet = false;
  39.                 var grossLine = null;
  40.                 var baseGrossPrice = 0;
  41.                 if (taxContainer) {
  42.                     var taxText = taxContainer.textContent || '';
  43.                     var rm = taxText.match(/(\d+)%\s*MwSt/i);
  44.                     if (rm) taxRate = parseInt(rm[1]);
  45.                     if (taxText.indexOf('exkl.') !== -1) displayIsNet = true;
  46.                     var taxP = taxContainer.querySelector('.product-detail-tax') || taxContainer.querySelector('p');
  47.                     if (taxP) {
  48.                         var childNodes = taxP.childNodes;
  49.                         for (var i = 0; i < childNodes.length; i++) {
  50.                             if (childNodes[i].nodeType === 3) {
  51.                                 var nodeText = childNodes[i].textContent || '';
  52.                                 if (nodeText.indexOf('inkl.') !== -1) {
  53.                                     grossLine = childNodes[i];
  54.                                     baseGrossPrice = parsePriceDE(nodeText);
  55.                                 }
  56.                             }
  57.                         }
  58.                     }
  59.                 }
  60.                 var baseNet, baseGross;
  61.                 if (displayIsNet) {
  62.                     baseNet = baseDisplayPrice;
  63.                     baseGross = baseGrossPrice > 0 ? baseGrossPrice : baseNet * (1 + taxRate / 100);
  64.                 } else {
  65.                     baseGross = baseDisplayPrice;
  66.                     baseNet = baseGross / (1 + taxRate / 100);
  67.                 }
  68.                 function getSelectedOptionsTotal() {
  69.                     var total = 0;
  70.                     document.querySelectorAll('.dkc-product-option-radio').forEach(function(r) {
  71.                         if (r.checked && r.value !== '') total += parseFloat(r.dataset.price || 0);
  72.                     });
  73.                     document.querySelectorAll('.dkc-product-option-checkbox').forEach(function(c) {
  74.                         if (c.checked) total += parseFloat(c.dataset.price || 0);
  75.                     });
  76.                     return total;
  77.                 }
  78.                 function updatePriceDisplay() {
  79.                     var optionsTotal = getSelectedOptionsTotal();
  80.                     var newNet = baseNet + optionsTotal;
  81.                     var newGross = newNet * (1 + taxRate / 100);
  82.                     var newDisplayPrice = displayIsNet ? newNet : newGross;
  83.                     if (priceElement) {
  84.                         priceElement.innerHTML = formatCurrency(newDisplayPrice) + '&nbsp;&euro;*';
  85.                     }
  86.                     if (grossLine) {
  87.                         var oldText = grossLine.textContent;
  88.                         grossLine.textContent = oldText.replace(
  89.                             /[\d.,]+\s*[\u00a0\s]*\u20ac/,
  90.                             formatCurrency(newGross) + '\u00a0\u20ac'
  91.                         );
  92.                     }
  93.                 }
  94.                 document.querySelectorAll('.dkc-product-option-radio, .dkc-product-option-checkbox').forEach(function(input) {
  95.                     input.addEventListener('change', updatePriceDisplay);
  96.                 });
  97.                 // Bei Reload: sofort pruefen ob etwas angehakt ist
  98.                 updatePriceDisplay();
  99.                 // === Warenkorb Submit-Handler ===
  100.                 addToCartForm.addEventListener('submit', function(event) {
  101.                     var selectedOptions = [];
  102.                     document.querySelectorAll('.dkc-product-option-radio').forEach(function(radio) {
  103.                         if (radio.checked && radio.value !== '') {
  104.                             selectedOptions.push({
  105.                                 id: radio.value,
  106.                                 name: radio.dataset.optionName,
  107.                                 price: parseFloat(radio.dataset.price || 0),
  108.                                 group: radio.dataset.group
  109.                             });
  110.                         }
  111.                     });
  112.                     document.querySelectorAll('.dkc-product-option-checkbox').forEach(function(cb) {
  113.                         if (cb.checked) {
  114.                             selectedOptions.push({
  115.                                 id: cb.value,
  116.                                 name: cb.dataset.optionName,
  117.                                 price: parseFloat(cb.dataset.price || 0),
  118.                                 group: cb.dataset.group
  119.                             });
  120.                         }
  121.                     });
  122.                     if (selectedOptions.length === 0) return;
  123.                     var lineItemKey = null;
  124.                     var lineItemRegex = /lineItems\[([^\]]+)\]/;
  125.                     var inputs = addToCartForm.querySelectorAll('input[name^="lineItems"]');
  126.                     for (var i = 0; i < inputs.length; i++) {
  127.                         var match = inputs[i].name.match(lineItemRegex);
  128.                         if (match && match[1]) {
  129.                             lineItemKey = match[1];
  130.                             break;
  131.                         }
  132.                     }
  133.                     if (!lineItemKey) return;
  134.                     addToCartForm.querySelectorAll('input[name*="dkc_product_options"]').forEach(function(el) { el.remove(); });
  135.                     var optionsInput = document.createElement('input');
  136.                     optionsInput.type = 'hidden';
  137.                     optionsInput.name = 'lineItems[' + lineItemKey + '][payload][dkc_product_options]';
  138.                     optionsInput.value = JSON.stringify(selectedOptions);
  139.                     addToCartForm.appendChild(optionsInput);
  140.                     var totalPrice = 0;
  141.                     for (var j = 0; j < selectedOptions.length; j++) {
  142.                         totalPrice += (selectedOptions[j].price || 0);
  143.                     }
  144.                     if (totalPrice > 0) {
  145.                         var priceInput = document.createElement('input');
  146.                         priceInput.type = 'hidden';
  147.                         priceInput.name = 'lineItems[' + lineItemKey + '][payload][dkc_product_options_price]';
  148.                         priceInput.value = totalPrice.toString();
  149.                         addToCartForm.appendChild(priceInput);
  150.                     }
  151.                     var labels = [];
  152.                     for (var k = 0; k < selectedOptions.length; k++) {
  153.                         labels.push(selectedOptions[k].name);
  154.                     }
  155.                     if (labels.length > 0) {
  156.                         var labelsInput = document.createElement('input');
  157.                         labelsInput.type = 'hidden';
  158.                         labelsInput.name = 'lineItems[' + lineItemKey + '][payload][dkc_product_options_labels]';
  159.                         labelsInput.value = JSON.stringify(labels);
  160.                         addToCartForm.appendChild(labelsInput);
  161.                     }
  162.                 });
  163.             });
  164.         </script>
  165.     {% endif %}
  166. {% endblock %}