Advertisement
oscarviedma

Código JS COD - OV DIVI

Oct 19th, 2024
509
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
HTML 14.82 KB | None | 0 0
  1. <script>
  2. // Configuración de moneda y formato
  3. const CURRENCY_CODE = 'MXN';
  4. const CURRENCY_SYMBOL = '$';
  5. const DECIMAL_PLACES = 2;
  6. const THOUSANDS_SEPARATOR = ',';
  7. const DECIMAL_SEPARATOR = '.';
  8.  
  9. // Definición del producto
  10. const product = {
  11.     name: "Nike Air Zoom TR 1",
  12.     basePrice: 2999.00,
  13.     attributes: [
  14.         {
  15.             name: "Color",
  16.             options: [
  17.                 { name: "Negro", image: "https://ovdemos.s3-tastewp.com/wp-content/uploads/2024/10/tenis-nike_c-negro.jpg" },
  18.                 { name: "Azul", priceAdjustment: -50, image: "https://ovdemos.s3-tastewp.com/wp-content/uploads/2024/10/tenis-nike_c-azul.jpg" },
  19.                 { name: "Turquesa", priceAdjustment: 50, image: "https://ovdemos.s3-tastewp.com/wp-content/uploads/2024/10/tenis-nike_c-negro-turquesa.jpg" },
  20.                 { name: "Naranja", image: "https://ovdemos.s3-tastewp.com/wp-content/uploads/2024/10/tenis-nike_c-naranja.jpg" }
  21.             ]
  22.         },
  23.         {
  24.             name: "Talla",
  25.             options: ["7", "7.5", "8", "8.5", "9", "9.5", "10"]
  26.         }
  27.     ],
  28.     defaultImage: "https://ovdemos.s3-tastewp.com/wp-content/uploads/2024/10/tenis-nike_c-negro.jpg",
  29.     thumbnails: [
  30.         "https://ovdemos.s3-tastewp.com/wp-content/uploads/2024/10/tenis-nike_c-negro-turquesa.jpg",
  31.         "https://ovdemos.s3-tastewp.com/wp-content/uploads/2024/10/tenis-nike_c-naranja.jpg",
  32.         "https://ovdemos.s3-tastewp.com/wp-content/uploads/2024/10/tenis-nike_c-azul.jpg"
  33.     ]
  34. };
  35.  
  36. // Configuración de opciones de envío
  37. const shippingOptions = {
  38.     Normal: {
  39.         name: "Envío normal",
  40.         price: 0,
  41.         time: "5-8 días"
  42.     },
  43.     Express: {
  44.         name: "Envío Express",
  45.         price: 90,
  46.         time: "1-3 días"
  47.     }
  48. };
  49.  
  50. // Variables globales
  51. let cart = [];
  52.  
  53. // Funciones
  54. function formatPrice(amount) {
  55.     if (typeof amount === 'number') {
  56.         return CURRENCY_SYMBOL + amount.toFixed(DECIMAL_PLACES).replace(/\d(?=(\d{3})+\.)/g, '$&' + THOUSANDS_SEPARATOR).replace('.', DECIMAL_SEPARATOR) + ' ' + CURRENCY_CODE;
  57.     } else if (typeof amount === 'string') {
  58.         return CURRENCY_SYMBOL + parseFloat(amount).toFixed(DECIMAL_PLACES).replace(/\d(?=(\d{3})+\.)/g, '$&' + THOUSANDS_SEPARATOR).replace('.', DECIMAL_SEPARATOR) + ' ' + CURRENCY_CODE;
  59.     } else {
  60.         return CURRENCY_SYMBOL + '0.00' + ' ' + CURRENCY_CODE;
  61.     }
  62. }
  63.  
  64. function generateThumbnails() {
  65.     const container = document.querySelector('.thumbnail-container');
  66.     container.innerHTML = '';
  67.  
  68.     const attributeWithImages = product.attributes.find(attr =>
  69.         attr.options.some(option => option.image)
  70.     );
  71.  
  72.     if (attributeWithImages) {
  73.         attributeWithImages.options.forEach((option, index) => {
  74.             if (option.image) {
  75.                 const img = document.createElement('img');
  76.                 img.src = option.image;
  77.                 img.alt = `Vista ${option.name}`;
  78.                 img.className = 'thumbnail';
  79.                 img.dataset.attributeName = attributeWithImages.name;
  80.                 img.dataset.attributeValue = option.name;
  81.                 img.addEventListener('click', function() {
  82.                     updateMainImage(this);
  83.                     updateAttributeSelection(this.dataset.attributeName, this.dataset.attributeValue);
  84.                 });
  85.                 container.appendChild(img);
  86.             }
  87.         });
  88.     } else {
  89.         const defaultThumb = document.createElement('img');
  90.         defaultThumb.src = product.defaultImage;
  91.         defaultThumb.alt = "Vista principal";
  92.         defaultThumb.className = 'thumbnail';
  93.         defaultThumb.addEventListener('click', function() {
  94.             updateMainImage(this);
  95.         });
  96.         container.appendChild(defaultThumb);
  97.     }
  98.  
  99.     if (container.children.length === 0) {
  100.         container.style.display = 'none';
  101.     }
  102. }
  103.  
  104. function generateAttributeSelectors() {
  105.     const container = document.getElementById('product-attributes');
  106.     container.innerHTML = '';
  107.  
  108.     product.attributes.forEach(attr => {
  109.         const label = document.createElement('label');
  110.         label.textContent = attr.name + ':';
  111.         container.appendChild(label);
  112.  
  113.         const buttonContainer = document.createElement('div');
  114.         buttonContainer.className = 'option-buttons';
  115.         buttonContainer.id = `${attr.name.toLowerCase()}-options`;
  116.  
  117.         attr.options.forEach(option => {
  118.             const button = document.createElement('button');
  119.             button.type = 'button';
  120.             button.className = 'option-button';
  121.  
  122.             if (typeof option === 'object') {
  123.                 button.dataset.value = option.name;
  124.                 button.dataset.priceAdjustment = option.priceAdjustment || 0;
  125.                 if (option.image) {
  126.                     button.dataset.image = option.image;
  127.                 }
  128.  
  129.                 let priceText = option.name;
  130.                 if (option.priceAdjustment) {
  131.                     if (option.priceAdjustment > 0) {
  132.                         priceText += ` (+${formatPrice(option.priceAdjustment)})`;
  133.                     } else {
  134.                         priceText += ` (-${formatPrice(Math.abs(option.priceAdjustment))})`;
  135.                     }
  136.                 }
  137.                 button.textContent = priceText;
  138.             } else {
  139.                 button.dataset.value = option;
  140.                 button.dataset.priceAdjustment = 0;
  141.                 button.textContent = option;
  142.             }
  143.  
  144.             buttonContainer.appendChild(button);
  145.         });
  146.  
  147.         container.appendChild(buttonContainer);
  148.     });
  149.  
  150.     document.querySelectorAll('.option-button').forEach(button => {
  151.         button.addEventListener('click', function() {
  152.             selectOption(this);
  153.         });
  154.     });
  155. }
  156.  
  157. function generateShippingOptions() {
  158.     const select = document.querySelector('.shipping-options');
  159.     select.innerHTML = '<option value="" disabled selected>Opciones de envío</option>';
  160.     for (const [key, option] of Object.entries(shippingOptions)) {
  161.         select.innerHTML += `<option value="${key}">${option.name} (${option.time}) - ${formatPrice(option.price)}</option>`;
  162.     }
  163. }
  164.  
  165. function updateMainImage(thumbnail) {
  166.     document.getElementById('main-image').src = thumbnail.src;
  167. }
  168.  
  169. function updateAttributeSelection(attributeName, value) {
  170.     const attributeContainer = document.getElementById(`${attributeName.toLowerCase()}-options`);
  171.     if (attributeContainer) {
  172.         const button = attributeContainer.querySelector(`[data-value="${value}"]`);
  173.         if (button) {
  174.             selectOption(button, false);
  175.         }
  176.     }
  177. }
  178.  
  179. function updatePrice() {
  180.     let totalPrice = product.basePrice;
  181.     product.attributes.forEach(attr => {
  182.         const selected = document.querySelector(`#${attr.name.toLowerCase()}-options .selected`);
  183.         if (selected) {
  184.             totalPrice += parseFloat(selected.dataset.priceAdjustment);
  185.         }
  186.     });
  187.     document.getElementById('product-price').textContent = formatPrice(totalPrice);
  188. }
  189.  
  190. function selectOption(button, updateImage = true) {
  191.     const attributeName = button.closest('.option-buttons').id.replace('-options', '');
  192.     button.parentElement.querySelectorAll('.option-button').forEach(btn => {
  193.         btn.classList.remove('selected');
  194.     });
  195.     button.classList.add('selected');
  196.  
  197.     if (updateImage && button.dataset.image) {
  198.        updateMainImage({ src: button.dataset.image });
  199.        
  200.         const thumbnails = document.querySelectorAll('.thumbnail');
  201.         thumbnails.forEach(thumb => {
  202.             if (thumb.dataset.attributeName === attributeName &&
  203.                thumb.dataset.attributeValue === button.dataset.value) {
  204.                thumb.classList.add('selected');
  205.             } else {
  206.                 thumb.classList.remove('selected');
  207.             }
  208.         });
  209.     }
  210.  
  211.     updatePrice();
  212. }
  213.  
  214. function updateCart() {
  215.     const cartItems = document.getElementById('cart-items');
  216.     const cartTotal = document.getElementById('cart-total');
  217.     const checkoutButton = document.getElementById('checkout');
  218.     const cartWarning = document.getElementById('cart-warning');
  219.     let total = 0;
  220.  
  221.     cartItems.innerHTML = '';
  222.     cart.forEach((item, index) => {
  223.         const li = document.createElement('li');
  224.         let itemDescription = `${item.name}`;
  225.         for (const [attrName, attrValue] of Object.entries(item.attributes)) {
  226.             itemDescription += ` - ${attrName}: ${attrValue}`;
  227.         }
  228.         li.innerHTML = `
  229.             ${itemDescription} - ${formatPrice(item.price)}
  230.             <button class="remove-item" data-index="${index}">&#x4d;</button>
  231.         `;
  232.         cartItems.appendChild(li);
  233.         total += item.price;
  234.     });
  235.  
  236.     cartTotal.textContent = formatPrice(total);
  237.     document.getElementById('whatsapp-total').textContent = formatPrice(total);
  238.  
  239.     if (cart.length > 0) {
  240.         checkoutButton.disabled = false;
  241.         cartWarning.style.display = 'none';
  242.     } else {
  243.         checkoutButton.disabled = true;
  244.         cartWarning.style.display = 'block';
  245.     }
  246. }
  247.  
  248. function showPopup() {
  249.     document.getElementById('popup').style.display = 'flex';
  250.  
  251.     const numProducts = cart.length;
  252.     document.getElementById('popup-product-name').textContent = `${product.name} x ${numProducts} productos`;
  253.  
  254.     updatePopupTotal();
  255.  
  256.     document.getElementById('popup-image').src = product.defaultImage;
  257. }
  258.  
  259. function updatePopupTotal() {
  260.     const shippingSelect = document.querySelector('.shipping-options');
  261.     const shippingCost = shippingOptions[shippingSelect.value]?.price || 0;
  262.     const total = cart.reduce((sum, item) => sum + item.price, 0) + shippingCost;
  263.     document.getElementById('popup-price').textContent = formatPrice(total);
  264.     document.getElementById('whatsapp-total').textContent = formatPrice(total);
  265. }
  266.  
  267. function closePopup() {
  268.     document.getElementById('popup').style.display = 'none';
  269. }
  270.  
  271. function clearCart() {
  272.     cart = [];
  273.     updateCart();
  274. }
  275.  
  276. function validateSelection() {
  277.     const warning = document.getElementById('attribute-warning');
  278.     const selectedAttributes = {};
  279.     let totalPrice = product.basePrice;
  280.  
  281.     const allSelected = product.attributes.every(attr => {
  282.         const selected = document.querySelector(`#${attr.name.toLowerCase()}-options .selected`);
  283.         if (selected) {
  284.             selectedAttributes[attr.name] = selected.dataset.value;
  285.             totalPrice += parseFloat(selected.dataset.priceAdjustment);
  286.             return true;
  287.         }
  288.         return false;
  289.     });
  290.  
  291.     if (!allSelected) {
  292.         warning.style.display = 'block';
  293.         return false;
  294.     }
  295.     warning.style.display = 'none';
  296.     return { valid: true, attributes: selectedAttributes, price: totalPrice };
  297. }
  298.  
  299. // Event Listeners
  300. document.addEventListener('DOMContentLoaded', function() {
  301.     document.getElementById('product-name').textContent = product.name;
  302.     document.getElementById('product-price').textContent = formatPrice(product.basePrice);
  303.     document.getElementById('main-image').src = product.defaultImage;
  304.     generateThumbnails();
  305.     generateAttributeSelectors();
  306.     generateShippingOptions();
  307.  
  308.     product.attributes.forEach(attr => {
  309.         const firstOption = document.querySelector(`#${attr.name.toLowerCase()}-options .option-button`);
  310.         if (firstOption) {
  311.             selectOption(firstOption);
  312.         }
  313.     });
  314. });
  315.  
  316. document.getElementById('add-to-cart').addEventListener('click', function() {
  317.     const result = validateSelection();
  318.     if (result.valid) {
  319.         const item = {
  320.             name: product.name,
  321.             price: result.price,
  322.             attributes: result.attributes
  323.         };
  324.         cart.push(item);
  325.         updateCart();
  326.     }
  327. });
  328.  
  329. document.getElementById('checkout').addEventListener('click', function() {
  330.     if (cart.length > 0) {
  331.         showPopup();
  332.     }
  333. });
  334.  
  335. document.getElementById('close-popup').addEventListener('click', closePopup);
  336.  
  337. document.getElementById('popup').addEventListener('click', function(e) {
  338.     if (e.target === this) {
  339.         closePopup();
  340.     }
  341. });
  342.  
  343. document.addEventListener('keydown', function(e) {
  344.     if (e.key === 'Escape') {
  345.         closePopup();
  346.     }
  347. });
  348.  
  349. document.getElementById('clear-cart').addEventListener('click', clearCart);
  350.  
  351. document.getElementById('cart-items').addEventListener('click', function(e) {
  352.     if (e.target.classList.contains('remove-item')) {
  353.         const index = e.target.dataset.index;
  354.         cart.splice(index, 1);
  355.         updateCart();
  356.     }
  357. });
  358.  
  359. document.querySelector('.shipping-options').addEventListener('change', updatePopupTotal);
  360.  
  361. document.getElementById('order-form').addEventListener('submit', function(e) {
  362.     e.preventDefault();
  363.     const formData = new FormData(this);
  364.     let message = `Nuevo pedido de ${product.name}:\n\n`;
  365.    
  366.     const fieldNames = {
  367.         nombres: "Nombre",
  368.         apellidos: "Apellidos",
  369.         calle_numero: "Calle y número",
  370.         colonia: "Colonia",
  371.         codigo_postal: "Código postal",
  372.         localidad: "Ciudad",
  373.         estado: "Estado",
  374.         pais: "País",
  375.         envio: "Método de envío",
  376.         pago: "Método de pago"
  377.     };
  378.  
  379.     for (let [key, value] of formData.entries()) {
  380.         let fieldName = fieldNames[key] || key.charAt(0).toUpperCase() + key.slice(1);
  381.         if (key === 'envio') {
  382.             const shippingOption = shippingOptions[value];
  383.             value = `${shippingOption.name} (${shippingOption.time}) - ${formatPrice(shippingOption.price)}`;
  384.         }
  385.         message += `${fieldName}: ${value}\n`;
  386.     }
  387.  
  388.     message += `\nProductos:\n`;
  389.     cart.forEach(item => {
  390.         let itemDescription = `• ${item.name}`;
  391.         for (const [attrName, attrValue] of Object.entries(item.attributes)) {
  392.             itemDescription += ` - ${attrName}: ${attrValue}`;
  393.         }
  394.         itemDescription += ` - ${formatPrice(item.price)}`;
  395.         message += itemDescription + '\n';
  396.     });
  397.  
  398.     const shippingSelect = document.querySelector('.shipping-options');
  399.     const shippingCost = shippingOptions[shippingSelect.value]?.price || 0;
  400.     const subtotal = cart.reduce((total, item) => total + item.price, 0);
  401.     const total = subtotal + shippingCost;
  402.  
  403.     message += `\nSubtotal: ${formatPrice(subtotal)}`;
  404.     message += `\nCosto de envío: ${formatPrice(shippingCost)}`;
  405.     message += `\nTotal: ${formatPrice(total)}`;
  406.  
  407.     const whatsappLink = `https://wa.me/529512345678?text=${encodeURIComponent(message)}`; // Reemplaza el número de WhatsApp
  408.     window.open(whatsappLink, '_blank');
  409. });
  410.  
  411. // Inicializar el carrito
  412. updateCart();
  413.  
  414. // Mover el div 'popup' después de 'et-main-area'
  415. var popup = document.getElementById('popup');
  416. var mainArea = document.getElementById('et-main-area');
  417. mainArea.parentNode.insertBefore(popup, mainArea.nextSibling);
  418. </script>
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement