Wijnkeuze

BAR VIN wijnkeuzehulp MAART 2026

Kies sneller, zonder wijnjargon.

1. Waar heb je nu zin in?
2. Welke smaakrichting spreekt je het meest aan?
3. Wat wil je vooral in de afdronk?
4. Houttoets oké?
5. Welke soort gerecht heb je?
7. Hoe wil je kiezen?

Aanbevolen glazen

Top 3 suggesties op basis van smaak en gerecht.

Nog geen selectie. Vul links je voorkeuren in en laat de tool het werk doen.
Toon alle wijnen en tags
`; }).join(''); } function initQuestions() { renderOptions('q-style', 'style', questions.style); renderOptions('q-profile', 'profile', questions.profile); renderOptions('q-body', 'body', questions.body); renderOptions('q-oak', 'oak', questions.oak); renderOptions('q-food-group', 'foodGroup', questions.foodGroup); renderOptions('q-adventure', 'adventure', questions.adventure); } function updateFoodDetails() { const group = document.querySelector('input[name="foodGroup"]:checked')?.value || ''; const detailOptions = foodDetailsByGroup[group] || []; if (group && detailOptions.length > 0) { renderOptions('q-food-detail', 'foodDetail', detailOptions); foodDetailQuestion.classList.remove('hidden'); } else { document.getElementById('q-food-detail').innerHTML = ''; foodDetailQuestion.classList.add('hidden'); } } function getAnswers() { const data = new FormData(document.getElementById('wineForm')); return { style: data.get('style') || '', profile: data.get('profile') || '', body: data.get('body') || '', oak: data.get('oak') || '', foodGroup: data.get('foodGroup') || '', foodDetail: data.get('foodDetail') || '', adventure: data.get('adventure') || '' }; } function labelForAnswer(group, value) { const allOptions = [ ...questions.style, ...questions.profile, ...questions.body, ...questions.oak, ...questions.foodGroup, ...questions.adventure, ...Object.values(foodDetailsByGroup).flat() ]; const found = allOptions.find(item => item.value === value); return found ? found.label : value; } function scoreWine(wine, answers) { let score = 0; for (const [key, value] of Object.entries(answers)) { if (!value || value === 'geen-idee' || value === 'maakt-niet-uit') continue; const desiredTags = (scoringMap[key] && scoringMap[key][value]) || []; const matched = desiredTags.filter(tag => wine.tags.includes(tag)); if (matched.length > 0) { score += matched.length * (weights[key] || 1); } } if (answers.style && answers.style !== 'geen-idee') { const exactStyle = scoringMap.style[answers.style]?.[0]; if (exactStyle && wine.tags.includes(exactStyle)) { score += 3; } else if (exactStyle) { score -= 4; } } if (answers.foodGroup === 'dessert' && wine.color !== 'sweet') score -= 6; if (answers.foodGroup === 'aperitief' && wine.tags.includes('dessert')) score -= 4; const lowerName = wine.name.toLowerCase(); const isHouseWine = lowerName.includes('huis'); if (isHouseWine) { score -= 6; } return { ...wine, score, isHouseWine }; } function recommendationText(wine, answers) { const detailSpecific = { oesters: { 121: 'Sterke match bij de gegratineerde oesters: fris, feestelijk en scherp genoeg om overeind te blijven.', 201: 'Klassiek sterke vismatch voor wie liever wit dan bubbels drinkt.' }, garnaalkroketten: { 121: 'Champagne en garnaalkroketten blijft gewoon een case study in gezond verstand.', 201: 'Frisse witte referentie als iemand geen bubbels wil.' }, 'steak-tartaar': { 462: 'Elegante roodkeuze die niet over het gerecht walst.', 473: 'Goede gastronomische match als de gast iets spannender wil.' }, rundsteak: { 474: 'Dit is de duidelijke power-match bij steak.', 472: 'Vol en rijp, maar net iets vriendelijker geprijsd.' }, moelleux: { 241: 'Speelse zoete keuze die het dessert lucht geeft.', 240: 'Zachtere dessertmatch voor wie minder sprankel wil.' } }; if (answers.foodDetail && detailSpecific[answers.foodDetail] && detailSpecific[answers.foodDetail][wine.id]) { return detailSpecific[answers.foodDetail][wine.id]; } return wine.description; } function renderResults(items, answers) { const results = document.getElementById('results'); const usable = items .filter(item => item.score > 0) .sort((a, b) => { if (a.isHouseWine !== b.isHouseWine) { return a.isHouseWine ? 1 : -1; } return b.score - a.score; }) .slice(0, 3); if (!usable.length) { results.innerHTML = '
Geen duidelijke match op basis van deze combinatie. Reset één of twee filters en probeer opnieuw.
'; return; } results.innerHTML = usable.map((wine, index) => `
${index + 1}. ${wine.name}
${[wine.producer, wine.region].filter(Boolean).join(' · ')}
${wine.glass} glas
${wine.bottle} fles
${wine.score >= 45 ? '⭐⭐⭐ Perfecte match' : wine.score >= 30 ? '⭐⭐ Sterke match' : '⭐ Goede keuze'}
${wine.grapes}
${wine.tags.slice(0, 6).map(tag => `${tag}`).join('')}
Waarom deze match: ${recommendationText(wine, answers)}
`).join(''); } function renderCatalog() { const catalog = document.getElementById('catalog'); catalog.innerHTML = wines.map(wine => `
${wine.name}${wine.producer ? ' — ' + wine.producer : ''}
${wine.color} · ${wine.glass} glas / ${wine.bottle} fles · ${wine.grapes}
${wine.tags.map(tag => `${tag}`).join(' ')}
`).join(''); } document.addEventListener('change', (e) => { if (e.target.name === 'foodGroup') { updateFoodDetails(); } }); document.getElementById('wineForm').addEventListener('submit', (e) => { e.preventDefault(); const answers = getAnswers(); const scored = wines.map(wine => scoreWine(wine, answers)); renderResults(scored, answers); }); document.getElementById('resetBtn').addEventListener('click', () => { document.getElementById('wineForm').reset(); document.getElementById('q-food-detail').innerHTML = ''; foodDetailQuestion.classList.add('hidden'); document.getElementById('results').innerHTML = '
Nog geen selectie. Vul links je voorkeuren in en laat de tool het werk doen.
'; }); initQuestions(); renderCatalog();