Matches in Stad Gent for { <https://stad.gent/id/infopage/832729> ?p ?o ?g. }
Showing items 1 to 12 of
12
with 100 items per page.
- 832729 type Article infopages.
- 832729 subject "https://stad.gent/en/node/3700" infopages.
- 832729 description "Bereken de prijs om een zaal te huren van Hartetroef." infopages.
- 832729 identifier "832729" infopages.
- 832729 inLanguage "nl" infopages.
- 832729 name "Hartetroef zaalverhuur - calculator" infopages.
- 832729 url 832729 infopages.
- 832729 dateModified "2026-06-25T08:07:47+00:00" infopages.
- 832729 datePublished "2026-04-29T09:03:51+00:00" infopages.
- 832729 articleBody " <div class="paragraph paragraph--type--embed paragraph--view-mode--full"> <section class="content-wrapper"> <div class="embed-wrapper"> <!-- Zaalverhuur Hartetroef — huurkost calculator | embed-fragment voor stad.gent --> <style> .rain-card { background:#fff; border-radius:8px; box-shadow:0 2px 8px rgba(0,0,0,.08); padding:1.5rem; max-width:48rem; margin-inline:auto; } .is-hidden { display:none !important; } /* Cards */ .card-grid { display:grid; grid-template-columns:repeat(2,1fr); gap:.5rem; } /* FIX L6-A11Y-08: visually-hidden i.p.v. display:none — inputs blijven in accessibility tree én tab-volgorde */ .hall-option input[type="checkbox"], .hall-option input[type="radio"] { position:absolute; width:1px; height:1px; padding:0; margin:-1px; overflow:hidden; clip:rect(0,0,0,0); white-space:nowrap; border:0; } .hall-option label { display:flex; flex-direction:column; align-items:center; justify-content:center; gap:.2rem; border:1px solid #ccc; border-radius:0; padding:.6rem .4rem; cursor:pointer; text-align:center; font-size:.85rem; line-height:1.25; transition:border-color .15s,background .15s; background:#fff; height:100%; box-sizing:border-box; } .hall-option label strong { font-size:.88rem; display:block; font-weight:600; } .hall-option label span.cap { font-size:.75rem; color:#555; font-weight:400; } .hall-option input:checked + label { border-color:#0072B8; background:#E6F8FF; } .hall-option label:hover { border-color:#0072B8; } /* FIX L6-A11Y-08: zichtbare focusring op het label wanneer de verborgen input focus heeft */ .hall-option input:focus-visible + label { outline:3px solid #003da5; outline-offset:2px; } /* Subtitel */ .form-sublabel { font-size:.75rem; color:#555; font-weight:400; margin:0 0 .6rem; display:block; text-align:left; } /* Tijden */ .datetime-row { display:grid; grid-template-columns:1fr 1fr 1fr; gap:.75rem; align-items:end; } .datetime-row .form-item { margin-bottom:0; } .datetime-row .form-item__label { font-weight:400; font-size:.75rem; color:#555; } #startTime, #endTime { font-weight:400; } @media(max-width:36em){ .datetime-row { grid-template-columns:1fr; } } /* Tooltip */ .tooltip-wrap { position:relative; display:inline-flex; align-items:center; } .tooltip-btn { display:inline-flex; align-items:center; justify-content:center; width:1.1rem; height:1.1rem; border-radius:50%; background:#00A3D9; color:#fff; font-size:.65rem; font-weight:700; border:none; cursor:pointer; margin-left:.6rem; line-height:1; flex-shrink:0; } .tooltip-box { display:none; position:absolute; bottom:calc(100% + .5rem); left:50%; transform:translateX(-50%); background:#E6F8FF; color:#000; border:none; border-radius:0; padding:.75rem 1rem; width:18rem; font-size:.88rem; font-weight:400; line-height:1.5; z-index:100; text-align:left; } .tooltip-box::after { content:''; position:absolute; top:100%; left:50%; transform:translateX(-50%); border:6px solid transparent; border-top-color:#E6F8FF; } .tooltip-box.is-open { display:block; } .tooltip-box ul { margin:.4rem 0 0; padding-left:1.1rem; } .tooltip-box li { margin-bottom:.2rem; } .tooltip-box p { margin:.4rem 0 0; font-size:.88rem; } .activity-label-row { display:inline-flex; align-items:center; flex-wrap:nowrap; } /* Form spacing */ .form-item { margin-bottom:1.25rem; } .form-item__label { margin-bottom:.5rem; font-size:.88rem; } /* FIX L6-A11Y-06: result-label vergroot van .7rem naar .8rem voor leesbaarheid */ .result-grid { display:grid; grid-template-columns:repeat(3,1fr); gap:.5rem; margin-top:1rem; } .teaser.teaser--background.no-image { background:#E6F8FF; border-radius:4px; } .teaser.no-image .teaser-content { text-align:center; padding:.7rem .5rem; } .result-label { font-size:.8rem; color:#555; margin:0 0 .15rem; text-transform:uppercase; letter-spacing:.04em; } .result-value { margin:0; font-size:.95rem; font-weight:700; line-height:1.25; word-break:break-word; } #hallResult { text-align:center; } @media(max-width:40em){ .result-value { font-size:.75rem; } .result-card-hall { display:none; } .result-grid { grid-template-columns:repeat(2,1fr); justify-content:center; } } .button-reset { margin-top:1.25rem; } .messages--info { margin-top:1rem !important; } .messages--info p { margin-bottom:.4rem; font-size:.88rem; } .messages--info ul { margin:.2rem 0 .4rem 1.2rem; font-size:.88rem; } .messages--info li { margin-bottom:.15rem; } select:invalid { color:gray; } /* FIX L6-A11Y-05: inline foutmeldingen */ .field-error { display:none; color:#c00; font-size:.82rem; margin-top:.35rem; } .field-error.is-visible { display:block; } </style> <div id="hallWidget" class="rain-card"> <form id="hallForm" class="form" novalidate> <h2 class="h2">Bereken de huurkost voor jouw evenement</h2> <p class="lead">Ontvang een inschatting van de totale huurkost.</p> <!-- 1. Zalen (meerdere selectie) --> <!-- role="group" + aria-labelledby geeft screenreader-semantiek zonder <legend>-browser-defaults --> <div class="form-item" role="group" aria-labelledby="label-hall"> <label id="label-hall" class="form-item__label">Welke zaal wil je huren?</label> <p class="form-sublabel">Je kan ook meerdere zalen aanduiden.</p> <div class="card-grid"> <div class="hall-option"> <input type="checkbox" name="hall" id="hall-keuken" value="keuken" /> <label for="hall-keuken"><strong>Buurtkeuken</strong><span class="cap">max. 12 personen</span></label> </div> <div class="hall-option"> <input type="checkbox" name="hall" id="hall-restaurant" value="restaurant" /> <label for="hall-restaurant"><strong>Restaurant</strong><span class="cap">max. 100 personen</span></label> </div> <div class="hall-option"> <input type="checkbox" name="hall" id="hall-koor" value="koor" /> <label for="hall-koor"><strong>Koorzaal</strong><span class="cap">max. 180 personen</span></label> </div> <div class="hall-option"> <input type="checkbox" name="hall" id="hall-orgel" value="orgel" /> <label for="hall-orgel"><strong>Orgelzaal</strong><span class="cap">max. 240 personen</span></label> </div> </div> <!-- FIX L6-A11Y-05: inline foutmelding i.p.v. alert() --> <p id="error-hall" class="field-error" role="alert">Kies minstens één zaal.</p> </div> <!-- 2. Wie ben je? --> <div class="form-item" role="group" aria-labelledby="label-renter"> <label id="label-renter" class="form-item__label">Wie ben je?</label> <div class="card-grid"> <div class="hall-option"> <input type="radio" name="renterType" id="renter-erkend" value="erkend" /> <label for="renter-erkend"> <strong>Erkende vereniging</strong> <span class="cap">Met erkenning of toelage van de Stad Gent</span> </label> </div> <div class="hall-option"> <input type="radio" name="renterType" id="renter-andere" value="andere" /> <label for="renter-andere"> <strong>Andere huurder</strong> <span class="cap">Niet-erkende vereniging, organisatie, bedrijf, privé</span> </label> </div> </div> <p id="error-renter" class="field-error" role="alert">Geef aan wie je bent.</p> </div> <!-- 3. Type activiteit --> <div class="form-item" role="group" aria-labelledby="label-activity"> <label id="label-activity" class="form-item__label">Welk type activiteit plan je?</label> <div class="card-grid"> <div class="hall-option"> <input type="radio" name="activityType" id="activity-socio" value="socio" /> <label for="activity-socio"> <strong> <span class="activity-label-row">Sociaal-culturele activiteit <span class="tooltip-wrap"> <!-- FIX L6-A11Y-03: aria-describedby koppelt tooltip-inhoud aan knop --> <button type="button" class="tooltip-btn" id="tooltipBtn" aria-label="Wat is een sociaal-culturele activiteit?" aria-describedby="tooltipBox" aria-expanded="false">i</button> <div class="tooltip-box" id="tooltipBox" role="tooltip"> Wat is een sociaal-culturele activiteit? <ul> <li>Publiek toegankelijk, of voor alle leden van een vereniging.</li> <li>Zonder winstoogmerk, of opbrengsten gaan naar een goed doel.</li> <li>Met maatschappelijk doel: ontmoeting, educatie, sociale of culturele ontplooiing.</li> </ul> </div> </span> </span> </strong> </label> </div> <div class="hall-option"> <input type="radio" name="activityType" id="activity-andere" value="andere" /> <label for="activity-andere"> <strong>Commerciële of privé-activiteit</strong> </label> </div> </div> <p id="error-activity" class="field-error" role="alert">Geef aan welk type activiteit je plant.</p> </div> <!-- 4. Tijden --> <div class="form-item"> <label class="form-item__label" id="timeGroupLabel">Hoe lang wil je huren?</label> <div class="datetime-row" role="group" aria-labelledby="timeGroupLabel"> <div class="form-item"> <label for="startTime" class="form-item__label">Starttijd</label> <select id="startTime" name="startTime" class="select"> <option value="" disabled hidden>Kies starttijd</option> <option value="07:00">07:00</option> <option value="08:00">08:00</option> <option value="09:00" selected>09:00</option> <option value="10:00">10:00</option> <option value="11:00">11:00</option> <option value="12:00">12:00</option> <option value="13:00">13:00</option> <option value="14:00">14:00</option> <option value="15:00">15:00</option> <option value="16:00">16:00</option> <option value="17:00">17:00</option> <option value="18:00">18:00</option> <option value="19:00">19:00</option> <option value="20:00">20:00</option> <option value="21:00">21:00</option> <option value="22:00">22:00</option> </select> </div> <div class="form-item"> <label for="endTime" class="form-item__label">Eindtijd</label> <select id="endTime" name="endTime" class="select"> <option value="" disabled hidden>Kies eindtijd</option> <option value="07:00">07:00</option> <option value="08:00">08:00</option> <option value="09:00">09:00</option> <option value="10:00">10:00</option> <option value="11:00">11:00</option> <option value="12:00">12:00</option> <option value="13:00">13:00</option> <option value="14:00">14:00</option> <option value="15:00">15:00</option> <option value="16:00">16:00</option> <option value="17:00" selected>17:00</option> <option value="18:00">18:00</option> <option value="19:00">19:00</option> <option value="20:00">20:00</option> <option value="21:00">21:00</option> <option value="22:00">22:00</option> </select> </div> <div class="form-item form-item--btn"> <label class="form-item__label" style="visibility:hidden;" aria-hidden="true"></label> <button class="button button-primary" type="submit" style="width:100%;">Bereken mijn huurkost</button> </div> </div> <p id="error-time" class="field-error" role="alert">De eindtijd moet na de starttijd liggen.</p> </div> <!-- Info-blok --> <div class="messages messages--info" role="note"> <div class="messages__content"> <h3 class="h4">Hoe werkt de berekening?</h3> <p>De huurprijs wordt bepaald door de zaal, je statuut als huurder en het type activiteit. Prijzen zijn per uur. Catering is niet inbegrepen.</p> <p><strong>De huur is gratis voor:</strong></p> <ul> <li>Groep Gent: voor eigen werking</li> <li>Adviesraden: voor eigen werking</li> <li>Onderwijsinstellingen in Gent: voor educatieve taken</li> </ul> <p> <!-- FIX L5-LINK-01: noreferrer toegevoegd --> <a class="link link--icon" href="https://stad.gent/nl/reglementen/retributiereglement-voor-het-beschikbaar-stellen-van-zalen" target="_blank" rel="noopener noreferrer">Meer info in het reglement<span class="link__icon" aria-hidden="true"></span></a> </p> </div> </div> </form> <!-- FIX L6-A11Y-07: aria-labelledby koppelt sectietitel aan landmark --> <section id="hallResult" class="is-hidden" aria-live="polite" aria-atomic="true" aria-labelledby="hallResultTitle"> <h2 id="hallResultTitle" class="h2">Jouw huurkost</h2> <p class="lead">De geschatte huurprijs voor jouw evenement bedraagt <strong>€ <span id="totalOut">–</span></strong> (excl. catering).</p> <div class="result-grid"> <article class="teaser teaser--background no-image result-card-hall"> <div class="teaser-content"> <p class="result-label">Zaal</p> <h3 id="detailHall" class="result-value">–</h3> </div> </article> <article class="teaser teaser--background no-image"> <div class="teaser-content"> <p class="result-label">Tijdstip</p> <h3 id="detailStart" class="result-value">–</h3> </div> </article> <article class="teaser teaser--background no-image"> <div class="teaser-content"> <p class="result-label">Duurtijd</p> <h3 id="detailDuration" class="result-value">–</h3> </div> </article> </div> <div class="button-reset" style="display:flex;flex-wrap:wrap;gap:1rem;align-items:center;justify-content:center;"> <button id="resetCalc" class="button button-primary" type="button">Bereken opnieuw</button> <!-- FIX L5-LINK-01: noreferrer toegevoegd --> <a id="zaalLink" href="#" target="_blank" rel="noopener noreferrer" class="button button-secondary">Bekijk beschikbaarheid</a> </div> </section> </div> <script> (function(){ 'use strict'; /* ── Statische tariefdata — geen user input, geen extern ophalen ── */ const RATES = { restaurant:{'erkend-socio':15,'erkend-andere':45,'andere-socio':26,'andere-andere':75}, orgel: {'erkend-socio':15,'erkend-andere':45,'andere-socio':26,'andere-andere':75}, koor: {'erkend-socio':8.5,'erkend-andere':25,'andere-socio':14.5,'andere-andere':42.5}, keuken: {'erkend-socio':2.5,'erkend-andere':7.5,'andere-socio':4.5,'andere-andere':12.5} }; /* Veilige whitelist: enkel bekende zaal-IDs en labels — nooit user-controlled */ const HALL_LABELS = Object.freeze({restaurant:'Restaurant',orgel:'Orgelzaal',koor:'Koorzaal',keuken:'Buurtkeuken'}); const ALLOWED_HALLS = Object.freeze(Object.keys(HALL_LABELS)); /* ZALENZOEKER-URLs: waarden zijn statisch, nooit afgeleid van user input */ const ZALENZOEKER = Object.freeze({ restaurant:'https://zalenzoeker.stad.gent/zalen/97b94fc4-4f2d-471f-8e59-4e9611c1c636', koor:'https://zalenzoeker.stad.gent/zalen/4137d337-866a-4a87-a8f4-2d75388ced4f', orgel:'https://zalenzoeker.stad.gent/zalen/d778780b-0aa6-49a8-b29b-1fa74f7eeca5', keuken:'https://zalenzoeker.stad.gent/zalen/b0a646f5-5e95-4e66-ad1d-28eda8e11ad5' }); const ALLOWED_RENTER = Object.freeze(['erkend','andere']); const ALLOWED_ACTIVITY = Object.freeze(['socio','andere']); /* Geldige tijdwaarden — selectopties zijn statisch, maar we valideren server-side-achtig */ const ALLOWED_TIMES = Object.freeze(['07:00','08:00','09:00','10:00','11:00','12:00','13:00','14:00','15:00','16:00','17:00','18:00','19:00','20:00','21:00','22:00']); const fmtDec2 = n => new Intl.NumberFormat('nl-BE',{minimumFractionDigits:2,maximumFractionDigits:2}).format(n); const durLabel = h => h === 0.5 ? '30 min' : Number.isInteger(h) ? h + ' uur' : Math.floor(h) + ' uur 30 min'; /* ── Tooltip ── */ const tooltipBtn = document.getElementById('tooltipBtn'); const tooltipBox = document.getElementById('tooltipBox'); tooltipBtn.addEventListener('click', e => { e.stopPropagation(); const isOpen = tooltipBox.classList.toggle('is-open'); tooltipBtn.setAttribute('aria-expanded', String(isOpen)); }); document.addEventListener('click', () => { tooltipBox.classList.remove('is-open'); tooltipBtn.setAttribute('aria-expanded', 'false'); }); /* ── Hulpfunctie: toon/verberg inline foutmelding ── */ function setError(id, visible) { const el = document.getElementById(id); if (!el) return; el.classList.toggle('is-visible', visible); } function clearAllErrors() { ['error-hall','error-renter','error-activity','error-time'].forEach(id => setError(id, false)); } /* ── Submit ── */ document.getElementById('hallForm').addEventListener('submit', e => { e.preventDefault(); clearAllErrors(); /* Verzamel waarden */ const rawHalls = [...document.querySelectorAll('input[name="hall"]:checked')].map(el => el.value); const rawRenter = (document.querySelector('input[name="renterType"]:checked') || {}).value; const rawAct = (document.querySelector('input[name="activityType"]:checked') || {}).value; const rawStart = document.getElementById('startTime').value; const rawEnd = document.getElementById('endTime').value; /* ── Validatie + whitelist-check (voorkomt prototype-pollution en injection) ── */ const halls = rawHalls.filter(v => ALLOWED_HALLS.includes(v)); const renter = ALLOWED_RENTER.includes(rawRenter) ? rawRenter : null; const activity = ALLOWED_ACTIVITY.includes(rawAct) ? rawAct : null; const start = ALLOWED_TIMES.includes(rawStart) ? rawStart : null; const end = ALLOWED_TIMES.includes(rawEnd) ? rawEnd : null; let hasError = false; if (!halls.length) { setError('error-hall', true); hasError = true; } if (!renter) { setError('error-renter', true); hasError = true; } if (!activity) { setError('error-activity', true); hasError = true; } if (hasError) { /* Zet focus op het eerste foutveld */ const first = document.querySelector('.field-error.is-visible'); if (first) first.focus(); return; } if (!start || !end) { setError('error-time', true); return; } const [sh] = start.split(':').map(Number); const [eh] = end.split(':').map(Number); const mins = (eh * 60) - (sh * 60); if (mins <= 0) { setError('error-time', true); return; } const hours = mins / 60; const key = renter + '-' + activity; const total = halls.reduce((s, h) => s + hours * RATES[h][key], 0); /* ── DOM-updates: uitsluitend via textContent — nooit innerHTML met variabelen ── */ document.getElementById('totalOut').textContent = fmtDec2(total); document.getElementById('detailHall').textContent = halls.map(h => HALL_LABELS[h]).join(' + '); document.getElementById('detailStart').textContent = start + ' \u2013 ' + end; document.getElementById('detailDuration').textContent = durLabel(hours); /* Zaallink: waarde komt uit statische whitelist-map, nooit uit user input */ document.getElementById('zaalLink').href = ZALENZOEKER[halls[0]]; document.getElementById('hallForm').classList.add('is-hidden'); const resultEl = document.getElementById('hallResult'); resultEl.classList.remove('is-hidden'); resultEl.setAttribute('tabindex', '-1'); resultEl.focus(); setTimeout(() => resultEl.removeAttribute('tabindex'), 800); }); /* ── Reset ── */ document.getElementById('resetCalc').addEventListener('click', () => { const savedStart = document.getElementById('startTime').value; const savedEnd = document.getElementById('endTime').value; const savedHalls = [...document.querySelectorAll('input[name="hall"]:checked')].map(el => el.value); const savedRenter = (document.querySelector('input[name="renterType"]:checked') || {}).value; const savedActivity = (document.querySelector('input[name="activityType"]:checked') || {}).value; document.querySelectorAll('input[name="hall"],input[name="renterType"],input[name="activityType"]') .forEach(el => { el.checked = false; }); /* Herstel tijden (waarden komen uit eigen select-elementen, geen user-typed input) */ if (ALLOWED_TIMES.includes(savedStart)) document.getElementById('startTime').value = savedStart; if (ALLOWED_TIMES.includes(savedEnd)) document.getElementById('endTime').value = savedEnd; /* Herstel selecties via whitelist */ savedHalls.filter(v => ALLOWED_HALLS.includes(v)).forEach(v => { const el = document.querySelector('input[name="hall"][value="' + v + '"]'); if (el) el.checked = true; }); if (ALLOWED_RENTER.includes(savedRenter)) { const el = document.querySelector('input[name="renterType"][value="' + savedRenter + '"]'); if (el) el.checked = true; } if (ALLOWED_ACTIVITY.includes(savedActivity)) { const el = document.querySelector('input[name="activityType"][value="' + savedActivity + '"]'); if (el) el.checked = true; } clearAllErrors(); document.getElementById('hallResult').classList.add('is-hidden'); document.getElementById('hallForm').classList.remove('is-hidden'); }); })(); </script> </div> </section> </div> " infopages.
- 832729 page 832729 infopages.
- 832729 articleSection "Sint-Amandsberg" infopages.