document.addEventListener('DOMContentLoaded', function() { // Elements const form = document.getElementById('mattressForm'); const formSteps = document.querySelectorAll('.mattress-form-step'); const progressBar = document.getElementById('progressBar'); const currentStepEl = document.getElementById('currentStep'); const totalStepsEl = document.getElementById('totalSteps'); const weightInput = document.getElementById('weight'); const weightValue = document.getElementById('weightValue'); const resultsSection = document.getElementById('resultsSection'); const resultsLoader = document.getElementById('resultsLoader'); const resultsContent = document.getElementById('resultsContent'); // Set total steps const totalSteps = formSteps.length; totalStepsEl.textContent = totalSteps; // Initialize let currentStep = 1; showStep(currentStep); updateProgressBar(); // Event listeners form.addEventListener('submit', handleSubmit); // Add event listeners to all next buttons document.querySelectorAll('.mattress-next-btn').forEach(button => { button.addEventListener('click', () => { if (validateStep(currentStep)) { nextStep(); } }); }); // Add event listeners to all previous buttons document.querySelectorAll('.mattress-prev-btn').forEach(button => { button.addEventListener('click', prevStep); }); // Weight slider weightInput.addEventListener('input', function() { weightValue.textContent = this.value + ' lbs'; }); // Functions function showStep(step) { formSteps.forEach(formStep => { formStep.classList.remove('active'); }); document.querySelector(`.mattress-form-step[data-step="${step}"]`).classList.add('active'); currentStepEl.textContent = step; } function nextStep() { if (currentStep < totalSteps) { currentStep++; showStep(currentStep); updateProgressBar(); } } function prevStep() { if (currentStep > 1) { currentStep--; showStep(currentStep); updateProgressBar(); } } function updateProgressBar() { const progress = ((currentStep - 1) / (totalSteps - 1)) * 100; progressBar.style.width = `${progress}%`; } function validateStep(step) { const currentStepEl = document.querySelector(`.mattress-form-step[data-step="${step}"]`); const requiredInputs = currentStepEl.querySelectorAll('input[required]'); let isValid = true; requiredInputs.forEach(input => { if (input.type === 'radio') { const radioGroup = currentStepEl.querySelectorAll(`input[name="${input.name}"]`); const isChecked = Array.from(radioGroup).some(radio => radio.checked); if (!isChecked) { isValid = false; highlightError(input.closest('.mattress-form-group')); } } else if (!input.value.trim()) { isValid = false; highlightError(input); } }); return isValid; } function highlightError(element) { element.classList.add('error'); // Add error message if it doesn't exist if (!element.querySelector('.mattress-error-message')) { const errorMessage = document.createElement('div'); errorMessage.className = 'mattress-error-message'; errorMessage.textContent = 'This field is required'; element.appendChild(errorMessage); } // Remove error after 3 seconds setTimeout(() => { element.classList.remove('error'); const errorMessage = element.querySelector('.mattress-error-message'); if (errorMessage) { errorMessage.remove(); } }, 3000); } function handleSubmit(e) { e.preventDefault(); if (!validateStep(currentStep)) { return; } // Hide form steps and show results section formSteps.forEach(step => step.classList.remove('active')); resultsSection.classList.add('active'); // Show loader resultsLoader.style.display = 'flex'; resultsContent.style.display = 'none'; // Get form data const formData = new FormData(form); const userData = {}; for (const [key, value] of formData.entries()) { userData[key] = value; } // Simulate API call/processing delay setTimeout(() => { // Generate recommendations const recommendations = generateRecommendations(userData); // Display results displayResults(recommendations); // Hide loader and show content resultsLoader.style.display = 'none'; resultsContent.style.display = 'block'; resultsContent.classList.add('active'); }, 2000); } function generateRecommendations(userData) { // This function contains the logic to determine mattress recommendations // based on user inputs. In a real implementation, this could be more complex // or even call an external API. let recommendations = []; let idealFirmness = calculateIdealFirmness(userData); // Determine mattress types based on user preferences and needs const recommendedTypes = determineRecommendedTypes(userData); // Generate specific mattress recommendations recommendations = generateSpecificRecommendations(userData, idealFirmness, recommendedTypes); return { firmness: idealFirmness, recommendations: recommendations, summary: generateSummary(userData, idealFirmness, recommendedTypes) }; } function calculateIdealFirmness(userData) { // Base firmness score (1-10 scale, 1 being softest, 10 being firmest) let firmness = 5; // Start with medium // Adjust based on sleep position switch (userData.sleepPosition) { case 'side': firmness -= 1.5; // Side sleepers need softer mattresses break; case 'back': firmness += 0.5; // Back sleepers need medium to medium-firm break; case 'stomach': firmness += 2; // Stomach sleepers need firmer mattresses break; case 'combination': firmness += 0; // Combination sleepers need medium break; } // Adjust based on weight const weight = parseInt(userData.weight); if (weight < 130) { firmness -= 1; // Lighter people need softer mattresses } else if (weight > 230) { firmness += 1.5; // Heavier people need firmer mattresses } // Adjust based on pain switch (userData.painArea) { case 'shoulderHip': firmness -= 1; // Pressure point pain needs softer mattresses break; case 'lowerBack': firmness += 1; // Lower back pain needs more support break; } // Adjust based on medical conditions switch (userData.medicalCondition) { case 'chronicPain': firmness -= 1; // Chronic pain often needs softer surfaces break; case 'arthritis': firmness -= 0.5; // Arthritis often needs pressure relief break; case 'sleepApnea': firmness += 0.5; // Sleep apnea/GERD may benefit from more support break; } // Adjust based on user preference switch (userData.firmness) { case 'soft': firmness -= 1.5; break; case 'medium': // No adjustment break; case 'firm': firmness += 1.5; break; } // Ensure firmness is within 1-10 range firmness = Math.max(1, Math.min(10, firmness)); return firmness; } function determineRecommendedTypes(userData) { let types = []; // If user has a preference, prioritize it if (userData.mattressType && userData.mattressType !== 'noPreference') { types.push(userData.mattressType); } // Add recommendations based on sleep position switch (userData.sleepPosition) { case 'side': types.push('memoryFoam', 'hybrid'); break; case 'back': types.push('latex', 'hybrid', 'innerspring'); break; case 'stomach': types.push('innerspring', 'firm'); break; case 'combination': types.push('hybrid', 'latex', 'responsive'); break; } // Add recommendations based on temperature if (userData.sleepTemperature === 'hot') { types.push('innerspring', 'latex', 'cooling'); } // Add recommendations based on motion transfer if (userData.motionTransfer === 'veryImportant') { types.push('memoryFoam'); } // Add recommendations based on allergies if (userData.allergies === 'dustMites') { types.push('latex', 'hypoallergenic'); } else if (userData.allergies === 'latex') { // Remove latex from recommendations types = types.filter(type => type !== 'latex'); types.push('memoryFoam'); } else if (userData.allergies === 'chemicalSensitivities') { types.push('organic', 'natural'); } // Add recommendations based on eco-friendly importance if (userData.ecoFriendly === 'veryImportant') { types.push('organic', 'natural', 'latex'); } // Remove duplicates types = [...new Set(types)]; return types; } function generateSpecificRecommendations(userData, firmness, types) { // This would typically come from a database of mattresses // For this example, we'll create some sample recommendations const mattressDatabase = [ { name: "Comfort Cloud Luxury Plush", type: "memoryFoam", firmness: 3, features: [ "Pressure-relieving memory foam", "Cooling gel-infused top layer", "Excellent motion isolation", "Ideal for side sleepers" ], idealFor: ["side", "shoulderHip", "chronicPain"], price: "$$", cooling: true, matchScore: 0 }, { name: "Supportive Hybrid Plus", type: "hybrid", firmness: 6, features: [ "Pocketed coil support system", "Responsive foam comfort layers", "Reinforced edge support", "Balanced feel for all sleep positions" ], idealFor: ["combination", "back", "couples"], price: "$$$", cooling: true, matchScore: 0 }, { name: "Natural Latex Harmony", type: "latex", firmness: 5, features: [ "100% natural Talalay latex", "Breathable and naturally cooling", "Responsive and supportive", "Eco-friendly materials" ], idealFor: ["back", "hot", "eco-conscious"], price: "$$$", cooling: true, matchScore: 0 }, { name: "Classic Innerspring Deluxe", type: "innerspring", firmness: 7, features: [ "Traditional coil system", "Firm supportive feel", "Excellent airflow", "Durable construction" ], idealFor: ["stomach", "back", "hot"], price: "$$", cooling: true, matchScore: 0 }, { name: "Organic Eco Comfort", type: "organic", firmness: 5, features: [ "GOTS-certified organic cotton", "Natural wool fire barrier", "No harmful chemicals", "Sustainable manufacturing" ], idealFor: ["eco-conscious", "chemicalSensitivities", "allergies"], price: "$$$$", cooling: true, matchScore: 0 }, { name: "Budget Comfort Essential", type: "memoryFoam", firmness: 6, features: [ "High-density support foam", "Affordable quality", "Medium-firm feel", "CertiPUR-US certified foams" ], idealFor: ["budget", "back", "average"], price: "$", cooling: false, matchScore: 0 }, { name: "Premium Adjustable Airbed", type: "airbed", firmness: 5, // Adjustable features: [ "Dual-zone adjustable firmness", "Remote controlled comfort", "Perfect for couples with different preferences", "Durable air chamber design" ], idealFor: ["couples", "yesDifferentNeeds", "back pain"], price: "$$$$", cooling: false, matchScore: 0 }, { name: "Luxury Hybrid Elite", type: "hybrid", firmness: 4, features: [ "Pillow-top comfort layer", "Zoned support system", "Premium materials", "Excellent pressure relief" ], idealFor: ["side", "back", "luxury"], price: "$$$$", cooling: true, matchScore: 0 } ]; // Calculate match scores for each mattress mattressDatabase.forEach(mattress => { let score = 0; // Firmness match (0-5 points) const firmnessDiff = Math.abs(mattress.firmness - firmness); if (firmnessDiff < 1) score += 5; else if (firmnessDiff < 2) score += 4; else if (firmnessDiff < 3) score += 3; else if (firmnessDiff < 4) score += 2; else score += 1; // Type match (0-3 points) if (types.includes(mattress.type)) score += 3; // Sleep position match (0-3 points) if (mattress.idealFor.includes(userData.sleepPosition)) score += 3; // Pain area match (0-2 points) if (userData.painArea !== 'none' && mattress.idealFor.includes(userData.painArea)) score += 2; // Temperature match (0-2 points) if (userData.sleepTemperature === 'hot' && mattress.cooling) score += 2; // Budget match (0-3 points) const priceMap = { '$': 1, '$$': 2, '$$$': 3, '$$$$': 4 }; const budgetMap = { 'under500': 1, '500to1000': 2, '1000to1500': 3, '1500to2000': 3, 'over2000': 4 }; const priceTier = priceMap[mattress.price]; const budgetTier = budgetMap[userData.budget]; if (priceTier <= budgetTier) score += 3; else if (priceTier === budgetTier + 1) score += 1; // Calculate percentage match (0-100%) mattress.matchScore = Math.round((score / 18) * 100); }); // Sort by match score and return top recommendations return mattressDatabase .sort((a, b) => b.matchScore - a.matchScore) .slice(0, 3); } function generateSummary(userData, firmness, types) { let summary = ''; // Sleep position switch (userData.sleepPosition) { case 'side': summary += 'As a side sleeper, you need a mattress that provides pressure relief for your shoulders and hips. '; break; case 'back': summary += 'As a back sleeper, you need a mattress that provides proper spinal alignment and support. '; break; case 'stomach': summary += 'As a stomach sleeper, you need a firmer mattress to prevent your midsection from sinking too deeply. '; break; case 'combination': summary += 'As a combination sleeper, you need a responsive mattress that allows for easy position changes. '; break; } // Firmness if (firmness < 4) { summary += 'Your ideal mattress should be soft to medium-soft (3-4/10 on the firmness scale). '; } else if (firmness < 7) { summary += 'Your ideal mattress should be medium to medium-firm (5-6/10 on the firmness scale). '; } else { summary += 'Your ideal mattress should be firm to very firm (7-8/10 on the firmness scale). '; } // Special considerations if (userData.painArea !== 'none') { summary += 'Given your pain concerns, look for mattresses with targeted support and pressure relief. '; } if (userData.sleepTemperature === 'hot') { summary += 'Since you sleep hot, prioritize mattresses with cooling features or naturally breathable materials. '; } if (userData.shareBed === 'yesDifferentNeeds') { summary += 'Since you share your bed with someone who has different needs, consider split firmness options or adjustable beds. '; } if (userData.motionTransfer === 'veryImportant') { summary += 'Motion isolation should be a priority in your mattress selection. '; } if (userData.allergies !== 'none') { summary += 'Due to your sensitivities, look for hypoallergenic materials and certifications for low chemical emissions. '; } return summary; } function displayResults(results) { // Clear previous results resultsContent.innerHTML = ''; // Create firmness scale const firmnessScale = document.createElement('div'); firmnessScale.className = 'mattress-firmness-scale'; const firmnessMarker = document.createElement('div'); firmnessMarker.className = 'mattress-firmness-marker'; firmnessMarker.style.left = `${(results.firmness / 10) * 100}%`; firmnessScale.appendChild(firmnessMarker); const firmnessLabels = document.createElement('div'); firmnessLabels.className = 'mattress-firmness-labels'; firmnessLabels.innerHTML = `
Soft (1) Medium (5) Firm (10) `; // Create summary box const summaryBox = document.createElement('div'); summaryBox.className = 'mattress-summary-box'; summaryBox.innerHTML = `
Your Sleep Profile
${results.summary}
Based on your inputs, we recommend a mattress with a firmness level of ${results.firmness.toFixed(1)}/10.
`; // Add firmness scale to summary box summaryBox.appendChild(firmnessScale); summaryBox.appendChild(firmnessLabels); // Add summary box to results resultsContent.appendChild(summaryBox); // Create recommendations section const recommendationsTitle = document.createElement('h3'); recommendationsTitle.textContent = 'Top Mattress Recommendations for You'; recommendationsTitle.style.marginTop = '30px'; recommendationsTitle.style.marginBottom = '20px'; resultsContent.appendChild(recommendationsTitle); // Add each recommendation results.recommendations.forEach(mattress => { const recommendationEl = document.createElement('div'); recommendationEl.className = 'mattress-recommendation'; // Convert price to dollar signs let priceDisplay = ''; switch (mattress.price) { case '$': priceDisplay = 'Budget-Friendly'; break; case '$$': priceDisplay = 'Moderate'; break; case '$$$': priceDisplay = 'Premium'; break; case '$$$$': priceDisplay = 'Luxury'; break; } // Create features list const featuresList = mattress.features.map(feature => `
${feature}`).join(''); recommendationEl.innerHTML = `
${mattress.name}
Type: ${formatMattressType(mattress.type)} | Firmness: ${formatFirmness(mattress.firmness)} | Price Range: ${priceDisplay}
${mattress.matchScore}% Match
`; resultsContent.appendChild(recommendationEl); }); // Add disclaimer const disclaimer = document.createElement('p'); disclaimer.style.fontSize = '0.8rem'; disclaimer.style.color = '#6c757d'; disclaimer.style.marginTop = '30px'; disclaimer.textContent = 'Note: These recommendations are based on your inputs and general mattress guidelines. Personal comfort preferences may vary. We recommend testing mattresses when possible before purchasing.'; resultsContent.appendChild(disclaimer); // Add reset button const resetButton = document.createElement('button'); resetButton.textContent = 'Start Over'; resetButton.className = 'mattress-submit-btn'; resetButton.style.marginTop = '20px'; resetButton.addEventListener('click', resetCalculator); resultsContent.appendChild(resetButton); } function formatMattressType(type) { const typeMap = { 'memoryFoam': 'Memory Foam', 'innerspring': 'Innerspring', 'hybrid': 'Hybrid', 'latex': 'Latex', 'airbed': 'Airbed', 'organic': 'Organic' }; return typeMap[type] || type; } function formatFirmness(firmness) { if (firmness <= 3) return 'Soft'; if (firmness <= 5) return 'Medium-Soft'; if (firmness <= 7) return 'Medium-Firm'; return 'Firm'; } function resetCalculator() { // Reset form form.reset(); // Reset to first step currentStep = 1; showStep(currentStep); updateProgressBar(); // Hide results section resultsSection.classList.remove('active'); resultsContent.classList.remove('active'); // Reset weight display weightValue.textContent = weightInput.value + ' lbs'; }
});