Untitled
unknown
plain_text
a month ago
12 kB
5
Indexable
{% comment %} Simple and Clean Bundle Selector - Fixed {% endcomment %} <div class="simple-bundle-selector"> <div class="simple-options-container"> {% for variant in product.variants %} {% if variant.title contains 'Pack' %} <div class="simple-option-item" id="option-item-{{ variant.id }}"> <input type="radio" value="{{ variant.id }}" name="simple_bundle_variant" id="simple_bundle_variant_{{ forloop.index }}" class="simple-variant-selector" data-variant-id="{{ variant.id }}" data-regular-price="{{ variant.price }}" data-compare-price="{{ variant.compare_at_price }}" {% if forloop.first %}checked{% endif %} > <label for="simple_bundle_variant_{{ forloop.index }}"> <div class="simple-option-content"> <div class="simple-option-header"> {% case variant.title %} {% when '2 Pack' or '2 pack' %}{% when '4 Pack' or '4 pack' %}<span class="best-seller">Best Seller</span>{% when '6 Pack' or '6 pack' %}<span class="best-value">Best Value</span> {% endcase %} </div> <div class="simple-circle"> {% case variant.title %} {% when '2 Pack' or '2 pack' %}2{% when '4 Pack' or '4 pack' %}4{% when '6 Pack' or '6 pack' %}6 {% endcase %} </div> <div class="simple-option-price"> {{ variant.price | money }} </div> {% if variant.compare_at_price > 0 %} <div class="simple-option-compare"> {{ variant.compare_at_price | money }} </div> {% endif %} </div> </label> </div> {% endif %} {% endfor %} </div> </div> <style> /* Base styles */ .simple-bundle-selector { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif; margin: 20px auto; max-width: 600px; perspective: 1000px; } .simple-options-container { display: flex; justify-content: center; gap: 10px; } .simple-option-item { position: relative; flex: 1; min-width: 0; flex-basis: 33.333%; transition: all 0.3s ease; } .simple-option-item input[type="radio"] { position: absolute; opacity: 0; } .simple-option-item label { display: block; cursor: pointer; border: 1px solid #e8e8e8; border-radius: 10px; padding: 15px 10px; background-color: #fff; transition: all 0.3s ease; height: 100%; } /* Selected state and hover effects */ .simple-option-item.selected label, .simple-option-item input[type="radio"]:checked + label { border-color: #de96b8; background-color: #fdf6fa; transform: translateY(-3px); box-shadow: 0 4px 12px rgba(222, 150, 184, 0.15); } .simple-option-item label:hover { transform: translateY(-2px); box-shadow: 0 3px 10px rgba(0, 0, 0, 0.05); } .simple-option-content { display: flex; flex-direction: column; align-items: center; text-align: center; } .simple-option-header { font-size: 14px; font-weight: 600; margin-bottom: 8px; min-height: 18px; } .best-seller, .best-value { display: inline-block; padding: 1px 5px; border-radius: 3px; font-weight: 500; font-size: 10px; background-color: #faeaf3; color: #d76ea3; transition: all 0.3s ease; } .simple-circle { width: 50px; height: 50px; border-radius: 50%; background-color: #f6e9f2; display: flex; align-items: center; justify-content: center; font-size: 24px; font-weight: 600; color: #8e5c7b; margin-bottom: 12px; transition: transform 0.3s ease, box-shadow 0.3s ease; } .simple-option-item input[type="radio"]:checked + label .simple-circle { transform: scale(1.08); box-shadow: 0 0 15px rgba(222, 150, 184, 0.2); } .simple-option-price { font-size: 16px; font-weight: 600; color: #333; margin-top: 4px; transition: all 0.3s ease; } .simple-option-item input[type="radio"]:checked + label .simple-option-price { color: #000; transform: scale(1.05); } .simple-option-compare { font-size: 14px; text-decoration: line-through; color: #999; margin-top: 2px; transition: opacity 0.3s ease; } /* Responsive styles */ @media (max-width: 480px) { .simple-option-header { font-size: 12px; margin-bottom: 6px; } .best-seller, .best-value { padding: 1px 4px; font-size: 9px; } .simple-circle { width: 40px; height: 40px; font-size: 20px; } .simple-option-price { font-size: 14px; } .simple-option-compare { font-size: 12px; } } @keyframes pulse { 0% { transform: scale(1); } 50% { transform: scale(1.15); } 100% { transform: scale(1.08); } } </style> <script> document.addEventListener('DOMContentLoaded', function() { // Initialize the bundle selector right away initBundleSelector(); // Also initialize after a short delay to ensure everything is loaded setTimeout(initBundleSelector, 500); function initBundleSelector() { // Get all option items and radio buttons const bundleItems = document.querySelectorAll('.simple-variant-selector'); const allOptionItems = document.querySelectorAll('.simple-option-item'); // Cart form elements const variantIdInputs = document.querySelectorAll('input[name="id"]'); // Find subscription elements const subscribeElement = document.querySelector('input[id*="subscribe"], [id*="subscription-option"]'); const oneTimeElement = document.querySelector('input[id*="one-time"]'); // Get subscription discount percentage const discountText = document.querySelector('[class*="save"]'); let discountPercent = 10; // Default 10% if (discountText) { const match = discountText.textContent.match(/\d+/); if (match) { discountPercent = parseInt(match[0], 10); } } // Function to update displayed prices function updatePrices() { const isSubscription = subscribeElement && subscribeElement.checked; bundleItems.forEach(item => { const priceElement = item.closest('.simple-option-item').querySelector('.simple-option-price'); const compareElement = item.closest('.simple-option-item').querySelector('.simple-option-compare'); const regularPrice = parseFloat(item.getAttribute('data-regular-price')); const comparePrice = parseFloat(item.getAttribute('data-compare-price')) || 0; if (priceElement && !isNaN(regularPrice)) { let finalPrice; if (isSubscription) { // Apply discount for subscription finalPrice = regularPrice * (1 - discountPercent / 100); } else { finalPrice = regularPrice; } // Format using Shopify's currency converter priceElement.textContent = formatMoney(finalPrice); // Update compare price if present if (compareElement && comparePrice > 0) { compareElement.textContent = formatMoney(comparePrice); } } }); } // Helper function to format money using Shopify's currency converter function formatMoney(cents) { if (typeof Shopify !== 'undefined' && Shopify.formatMoney) { return Shopify.formatMoney(cents); } // Simple fallback if Shopify formatter isn't available return '$' + (cents / 100).toFixed(2); } // Function to update the visual selection state function updateSelectionState() { // Remove selected class from all items allOptionItems.forEach(item => { item.classList.remove('selected'); }); // Find the checked radio button and add selected class to its parent const checkedRadio = document.querySelector('.simple-variant-selector:checked'); if (checkedRadio) { checkedRadio.closest('.simple-option-item').classList.add('selected'); } } // Update all variant inputs on the page function updateVariantSelection(variantId) { variantIdInputs.forEach(input => { input.value = variantId; }); // Find main product form const mainProductForm = document.querySelector('form[action="/cart/add"]'); if (mainProductForm) { const mainFormVariantInput = mainProductForm.querySelector('input[name="id"]'); if (mainFormVariantInput) { mainFormVariantInput.value = variantId; mainFormVariantInput.dispatchEvent(new Event('change', { bubbles: true })); } } // Get the subscription app dropdown if it exists and update it const subscriptionDropdown = document.querySelector('.rc_widget__option_selector, [id*="purchase-options"]'); if (subscriptionDropdown) { subscriptionDropdown.value = variantId; subscriptionDropdown.dispatchEvent(new Event('change', { bubbles: true })); } } // Handle bundle selection bundleItems.forEach(item => { item.addEventListener('change', function() { const variantId = this.value; // Update the form updateVariantSelection(variantId); // Update visual selection state updateSelectionState(); // Add pulse animation to the circle const circle = this.closest('.simple-option-item').querySelector('.simple-circle'); circle.style.animation = 'none'; setTimeout(() => { circle.style.animation = 'pulse 0.6s'; }, 10); }); }); // Listen for subscription option changes if (subscribeElement) { subscribeElement.addEventListener('change', updatePrices); } if (oneTimeElement) { oneTimeElement.addEventListener('change', updatePrices); } // Watch for DOM changes that might affect pricing document.addEventListener('click', function() { setTimeout(updatePrices, 100); }); // Monitor the subscription app elements for changes const subscriptionContainer = document.querySelector('.rc_container, .purchase-options-container, [class*="subscription"]'); if (subscriptionContainer) { const subscriptionObserver = new MutationObserver(function(mutations) { updatePrices(); }); subscriptionObserver.observe(subscriptionContainer, { childList: true, subtree: true, characterData: true, attributes: true }); } // Also listen for variant changes from the subscription app const subscriptionDropdown = document.querySelector('.rc_widget__option_selector, [id*="purchase-options"]'); if (subscriptionDropdown) { subscriptionDropdown.addEventListener('change', function() { // Find corresponding bundle variant const selectedVariantId = this.value; bundleItems.forEach(item => { if (item.value === selectedVariantId) { item.checked = true; updateSelectionState(); } }); }); } // When a product variant selection changes outside our bundle document.addEventListener('variant:changed', function(event) { if (event.detail && event.detail.variant) { const newVariantId = event.detail.variant.id.toString(); bundleItems.forEach(item => { if (item.value === newVariantId) { item.checked = true; updateSelectionState(); } }); } }); // Initial setup updateSelectionState(); updatePrices(); } }); </script>
Editor is loading...
Leave a Comment