{"id":9,"date":"2026-08-24T08:39:47","date_gmt":"2026-08-24T08:39:47","guid":{"rendered":"https:\/\/offerte.bizzbetter.nl\/?page_id=9"},"modified":"2026-08-24T08:40:47","modified_gmt":"2026-08-24T08:40:47","slug":"elementor-9","status":"publish","type":"page","link":"https:\/\/offerte.bizzbetter.nl\/?page_id=9","title":{"rendered":"Elementor #9"},"content":{"rendered":"\t\t<div data-elementor-type=\"wp-post\" data-elementor-id=\"9\" class=\"elementor elementor-9\">\n\t\t\t\t<div class=\"elementor-element elementor-element-ccc57c7 e-con-full e-flex e-con e-parent\" data-id=\"ccc57c7\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t<div class=\"elementor-element elementor-element-905f1b5 elementor-widget elementor-widget-html\" data-id=\"905f1b5\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"html.default\">\n\t\t\t\t\t<!doctype html>\n<html lang=\"nl\">\n<head>\n  <meta charset=\"utf-8\" \/>\n  <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" \/>\n  <title>Catering Offerte Generator<\/title>\n  <style>\n    :root {\n      --bg: #f6f4ef;\n      --card: #ffffff;\n      --text: #202020;\n      --muted: #6b6b6b;\n      --border: #dedbd3;\n      --accent: #1f6f54;\n      --accent-dark: #185641;\n      --danger: #a33b3b;\n    }\n\n    * { box-sizing: border-box; }\n    body {\n      margin: 0;\n      font-family: Inter, Arial, sans-serif;\n      background: var(--bg);\n      color: var(--text);\n    }\n\n    .wrap {\n      max-width: 1180px;\n      margin: 0 auto;\n      padding: 32px 20px 60px;\n    }\n\n    header {\n      margin-bottom: 24px;\n    }\n\n    h1 {\n      margin: 0 0 8px;\n      font-size: clamp(30px, 4vw, 48px);\n      line-height: 1.05;\n    }\n\n    header p {\n      margin: 0;\n      color: var(--muted);\n      max-width: 720px;\n    }\n\n    .grid {\n      display: grid;\n      grid-template-columns: minmax(0, 1.05fr) minmax(360px, .95fr);\n      gap: 24px;\n      align-items: start;\n    }\n\n    .card {\n      background: var(--card);\n      border: 1px solid var(--border);\n      border-radius: 18px;\n      padding: 24px;\n      box-shadow: 0 8px 30px rgba(0,0,0,.04);\n    }\n\n    h2 {\n      margin-top: 0;\n      font-size: 22px;\n    }\n\n    h3 {\n      margin: 26px 0 12px;\n      font-size: 15px;\n      text-transform: uppercase;\n      letter-spacing: .08em;\n      color: var(--muted);\n    }\n\n    .fields {\n      display: grid;\n      grid-template-columns: 1fr 1fr;\n      gap: 14px;\n    }\n\n    .full { grid-column: 1 \/ -1; }\n\n    label {\n      display: block;\n      font-size: 13px;\n      font-weight: 700;\n      margin-bottom: 6px;\n    }\n\n    input, select, textarea {\n      width: 100%;\n      padding: 12px 13px;\n      border: 1px solid var(--border);\n      border-radius: 10px;\n      background: white;\n      font: inherit;\n      color: inherit;\n      outline: none;\n    }\n\n    input:focus, select:focus, textarea:focus {\n      border-color: var(--accent);\n      box-shadow: 0 0 0 3px rgba(31,111,84,.10);\n    }\n\n    textarea { min-height: 90px; resize: vertical; }\n\n    .extras {\n      display: grid;\n      gap: 10px;\n    }\n\n    .extra {\n      display: grid;\n      grid-template-columns: 22px 1fr auto;\n      gap: 10px;\n      align-items: center;\n      padding: 12px;\n      border: 1px solid var(--border);\n      border-radius: 10px;\n    }\n\n    .extra input { width: auto; }\n    .price { color: var(--muted); font-size: 13px; }\n\n    .quote {\n      position: sticky;\n      top: 18px;\n    }\n\n    .brand {\n      display: flex;\n      align-items: center;\n      justify-content: space-between;\n      gap: 20px;\n      padding-bottom: 18px;\n      border-bottom: 1px solid var(--border);\n    }\n\n    .brand-name {\n      font-size: 20px;\n      font-weight: 800;\n    }\n\n    .badge {\n      padding: 7px 10px;\n      border-radius: 999px;\n      background: #e8f2ed;\n      color: var(--accent-dark);\n      font-size: 12px;\n      font-weight: 800;\n    }\n\n    .summary {\n      margin-top: 18px;\n    }\n\n    .line {\n      display: flex;\n      justify-content: space-between;\n      gap: 18px;\n      padding: 9px 0;\n      border-bottom: 1px dashed #e8e5df;\n    }\n\n    .line strong { text-align: right; }\n\n    .totals {\n      margin-top: 18px;\n      padding-top: 14px;\n      border-top: 2px solid var(--text);\n    }\n\n    .total {\n      display: flex;\n      justify-content: space-between;\n      padding: 7px 0;\n      font-size: 15px;\n    }\n\n    .grand {\n      font-size: 24px;\n      font-weight: 900;\n      color: var(--accent-dark);\n    }\n\n    .actions {\n      display: grid;\n      grid-template-columns: 1fr;\n      gap: 10px;\n      margin-top: 22px;\n    }\n\n    button {\n      border: 0;\n      border-radius: 11px;\n      padding: 14px 18px;\n      font: inherit;\n      font-weight: 800;\n      cursor: pointer;\n    }\n\n    .primary {\n      background: var(--accent);\n      color: white;\n    }\n\n    .primary:hover { background: var(--accent-dark); }\n\n    .secondary {\n      background: #ece9e2;\n      color: var(--text);\n    }\n\n    .small {\n      font-size: 12px;\n      color: var(--muted);\n      margin-top: 12px;\n      line-height: 1.5;\n    }\n\n    .notice {\n      display: none;\n      background: #fff4d6;\n      border: 1px solid #f0d88a;\n      padding: 10px 12px;\n      border-radius: 9px;\n      margin-top: 12px;\n      font-size: 13px;\n    }\n\n    @media (max-width: 860px) {\n      .grid { grid-template-columns: 1fr; }\n      .quote { position: static; }\n    }\n\n    @media (max-width: 580px) {\n      .fields { grid-template-columns: 1fr; }\n      .full { grid-column: auto; }\n      .wrap { padding: 20px 12px 40px; }\n      .card { padding: 18px; }\n    }\n  <\/style>\n<\/head>\n<body>\n  <div class=\"wrap\">\n    <header>\n      <h1>Catering offerte generator<\/h1>\n      <p>Voorbeeld van een eenvoudige self-service offerteflow. De bezoeker vult de aanvraag in, ziet direct een prijsindicatie en kan vervolgens een nette PDF-offerte downloaden.<\/p>\n    <\/header>\n\n    <div class=\"grid\">\n      <section class=\"card\">\n        <h2>1. Stel je catering samen<\/h2>\n\n        <h3>Klantgegevens<\/h3>\n        <div class=\"fields\">\n          <div>\n            <label for=\"name\">Naam<\/label>\n            <input id=\"name\" placeholder=\"Jan de Vries\" \/>\n          <\/div>\n          <div>\n            <label for=\"company\">Bedrijfsnaam<\/label>\n            <input id=\"company\" placeholder=\"Voorbeeld B.V.\" \/>\n          <\/div>\n          <div>\n            <label for=\"email\">E-mail<\/label>\n            <input id=\"email\" type=\"email\" placeholder=\"jan@voorbeeld.nl\" \/>\n          <\/div>\n          <div>\n            <label for=\"phone\">Telefoon<\/label>\n            <input id=\"phone\" placeholder=\"06 12345678\" \/>\n          <\/div>\n        <\/div>\n\n        <h3>Evenement<\/h3>\n        <div class=\"fields\">\n          <div>\n            <label for=\"date\">Datum<\/label>\n            <input id=\"date\" type=\"date\" \/>\n          <\/div>\n          <div>\n            <label for=\"guests\">Aantal personen<\/label>\n            <input id=\"guests\" type=\"number\" min=\"10\" value=\"50\" \/>\n          <\/div>\n          <div class=\"full\">\n            <label for=\"package\">Cateringpakket<\/label>\n            <select id=\"package\">\n              <option value=\"19.50\">Lunch basis \u2014 \u20ac 19,50 p.p.<\/option>\n              <option value=\"27.50\">Lunch deluxe \u2014 \u20ac 27,50 p.p.<\/option>\n              <option value=\"34.50\">Borrel & bites \u2014 \u20ac 34,50 p.p.<\/option>\n              <option value=\"42.50\" selected>Diner buffet \u2014 \u20ac 42,50 p.p.<\/option>\n              <option value=\"59.50\">Walking dinner \u2014 \u20ac 59,50 p.p.<\/option>\n            <\/select>\n          <\/div>\n          <div class=\"full\">\n            <label for=\"location\">Locatie \/ plaats<\/label>\n            <input id=\"location\" placeholder=\"Amsterdam\" \/>\n          <\/div>\n        <\/div>\n\n        <h3>Extra opties<\/h3>\n        <div class=\"extras\">\n          <label class=\"extra\">\n            <input class=\"extraCheck\" type=\"checkbox\" data-name=\"Drankenarrangement\" data-type=\"perPerson\" data-price=\"12.5\" \/>\n            <span>Drankenarrangement<\/span>\n            <span class=\"price\">\u20ac 12,50 p.p.<\/span>\n          <\/label>\n\n          <label class=\"extra\">\n            <input class=\"extraCheck\" type=\"checkbox\" data-name=\"Bediening op locatie\" data-type=\"fixed\" data-price=\"325\" \/>\n            <span>Bediening op locatie<\/span>\n            <span class=\"price\">\u20ac 325<\/span>\n          <\/label>\n\n          <label class=\"extra\">\n            <input class=\"extraCheck\" type=\"checkbox\" data-name=\"Servies & glaswerk\" data-type=\"perPerson\" data-price=\"4.5\" \/>\n            <span>Servies & glaswerk<\/span>\n            <span class=\"price\">\u20ac 4,50 p.p.<\/span>\n          <\/label>\n\n          <label class=\"extra\">\n            <input class=\"extraCheck\" type=\"checkbox\" data-name=\"Linnen & aankleding\" data-type=\"fixed\" data-price=\"175\" \/>\n            <span>Linnen & aankleding<\/span>\n            <span class=\"price\">\u20ac 175<\/span>\n          <\/label>\n\n          <label class=\"extra\">\n            <input class=\"extraCheck\" type=\"checkbox\" data-name=\"Dessertupgrade\" data-type=\"perPerson\" data-price=\"7.5\" \/>\n            <span>Dessertupgrade<\/span>\n            <span class=\"price\">\u20ac 7,50 p.p.<\/span>\n          <\/label>\n        <\/div>\n\n        <h3>Opmerkingen<\/h3>\n        <textarea id=\"notes\" placeholder=\"Bijvoorbeeld: vegetarische gasten, allergie\u00ebn, gewenste opbouwtijd...\"><\/textarea>\n      <\/section>\n\n      <aside class=\"card quote\">\n        <div class=\"brand\">\n          <div>\n            <div class=\"brand-name\">Smaakmakers Catering<\/div>\n            <div class=\"small\">Voorbeeldofferte<\/div>\n          <\/div>\n          <div class=\"badge\">Direct berekend<\/div>\n        <\/div>\n\n        <div class=\"summary\" id=\"summary\"><\/div>\n\n        <div class=\"totals\">\n          <div class=\"total\"><span>Subtotaal excl. btw<\/span><strong id=\"subtotal\">\u20ac 0,00<\/strong><\/div>\n          <div class=\"total\"><span>Btw 9%<\/span><strong id=\"vat\">\u20ac 0,00<\/strong><\/div>\n          <div class=\"total grand\"><span>Totaal incl. btw<\/span><strong id=\"grand\">\u20ac 0,00<\/strong><\/div>\n        <\/div>\n\n        <div class=\"actions\">\n          <button class=\"primary\" id=\"downloadBtn\">Download offerte als PDF<\/button>\n          <button class=\"secondary\" id=\"resetBtn\">Formulier opnieuw instellen<\/button>\n        <\/div>\n\n        <div class=\"notice\" id=\"notice\"><\/div>\n        <p class=\"small\">Dit is een prijsindicatie. Definitieve beschikbaarheid, reistijd, dieetwensen en maatwerk kunnen nog invloed hebben op de eindprijs.<\/p>\n      <\/aside>\n    <\/div>\n  <\/div>\n\n  <script src=\"https:\/\/cdnjs.cloudflare.com\/ajax\/libs\/jspdf\/2.5.1\/jspdf.umd.min.js\"><\/script>\n  <script>\n    const $ = (id) => document.getElementById(id);\n    const currency = new Intl.NumberFormat('nl-NL', {\n      style: 'currency',\n      currency: 'EUR'\n    });\n\n    const packageNames = {\n      \"19.50\": \"Lunch basis\",\n      \"27.50\": \"Lunch deluxe\",\n      \"34.50\": \"Borrel & bites\",\n      \"42.50\": \"Diner buffet\",\n      \"59.50\": \"Walking dinner\"\n    };\n\n    function getData() {\n      const guests = Math.max(0, Number($('guests').value || 0));\n      const packagePrice = Number($('package').value);\n      const packageName = packageNames[$('package').value];\n\n      const extras = [...document.querySelectorAll('.extraCheck:checked')].map(el => {\n        const price = Number(el.dataset.price);\n        const type = el.dataset.type;\n        return {\n          name: el.dataset.name,\n          price,\n          type,\n          total: type === 'perPerson' ? price * guests : price\n        };\n      });\n\n      const packageTotal = packagePrice * guests;\n      const extrasTotal = extras.reduce((sum, x) => sum + x.total, 0);\n\n      \/\/ Voorbeeld: vaste transport-\/logistiekkosten.\n      const logistics = guests > 0 ? 95 : 0;\n      const subtotal = packageTotal + extrasTotal + logistics;\n      const vat = subtotal * 0.09;\n      const grand = subtotal + vat;\n\n      return {\n        name: $('name').value.trim(),\n        company: $('company').value.trim(),\n        email: $('email').value.trim(),\n        phone: $('phone').value.trim(),\n        date: $('date').value,\n        guests,\n        location: $('location').value.trim(),\n        notes: $('notes').value.trim(),\n        packageName,\n        packagePrice,\n        packageTotal,\n        extras,\n        logistics,\n        subtotal,\n        vat,\n        grand\n      };\n    }\n\n    function fmtDate(iso) {\n      if (!iso) return 'Nog te bepalen';\n      const d = new Date(iso + 'T12:00:00');\n      return d.toLocaleDateString('nl-NL', { day: '2-digit', month: 'long', year: 'numeric' });\n    }\n\n    function update() {\n      const d = getData();\n\n      let html = `\n        <div class=\"line\"><span>Arrangement<\/span><strong>${d.packageName}<\/strong><\/div>\n        <div class=\"line\"><span>Aantal gasten<\/span><strong>${d.guests}<\/strong><\/div>\n        <div class=\"line\"><span>Prijs arrangement<\/span><strong>${currency.format(d.packageTotal)}<\/strong><\/div>\n      `;\n\n      d.extras.forEach(x => {\n        html += `<div class=\"line\"><span>${x.name}<\/span><strong>${currency.format(x.total)}<\/strong><\/div>`;\n      });\n\n      html += `<div class=\"line\"><span>Logistiek \/ transport<\/span><strong>${currency.format(d.logistics)}<\/strong><\/div>`;\n\n      $('summary').innerHTML = html;\n      $('subtotal').textContent = currency.format(d.subtotal);\n      $('vat').textContent = currency.format(d.vat);\n      $('grand').textContent = currency.format(d.grand);\n    }\n\n    function validate(d) {\n      if (!d.name) return 'Vul eerst een naam in.';\n      if (!d.email) return 'Vul eerst een e-mailadres in.';\n      if (!d.guests || d.guests < 10) return 'Vul minimaal 10 gasten in.';\n      return '';\n    }\n\n    async function downloadPDF() {\n      const d = getData();\n      const error = validate(d);\n      const notice = $('notice');\n\n      if (error) {\n        notice.textContent = error;\n        notice.style.display = 'block';\n        return;\n      }\n\n      notice.style.display = 'none';\n\n      if (!window.jspdf) {\n        notice.textContent = 'De PDF-module kon niet worden geladen. Controleer je internetverbinding en probeer opnieuw.';\n        notice.style.display = 'block';\n        return;\n      }\n\n      const { jsPDF } = window.jspdf;\n      const doc = new jsPDF({ unit: 'mm', format: 'a4' });\n\n      const left = 18;\n      const right = 192;\n      let y = 20;\n\n      doc.setFont('helvetica', 'bold');\n      doc.setFontSize(21);\n      doc.text('Smaakmakers Catering', left, y);\n\n      doc.setFont('helvetica', 'normal');\n      doc.setFontSize(10);\n      doc.text('Voorbeeldofferte catering', left, y + 7);\n\n      const quoteNo = 'OFF-' + new Date().getFullYear() + '-' + String(Date.now()).slice(-6);\n      doc.text('Offertenummer: ' + quoteNo, 130, y);\n      doc.text('Datum: ' + new Date().toLocaleDateString('nl-NL'), 130, y + 6);\n\n      y += 22;\n      doc.setDrawColor(205);\n      doc.line(left, y, right, y);\n      y += 10;\n\n      doc.setFont('helvetica', 'bold');\n      doc.setFontSize(12);\n      doc.text('Klantgegevens', left, y);\n      y += 7;\n\n      doc.setFont('helvetica', 'normal');\n      doc.setFontSize(10);\n      const customer = [\n        d.name,\n        d.company,\n        d.email,\n        d.phone,\n      ].filter(Boolean);\n\n      customer.forEach(t => {\n        doc.text(String(t), left, y);\n        y += 5.5;\n      });\n\n      y += 4;\n      doc.setFont('helvetica', 'bold');\n      doc.setFontSize(12);\n      doc.text('Evenement', left, y);\n      y += 7;\n\n      doc.setFont('helvetica', 'normal');\n      doc.setFontSize(10);\n      doc.text('Datum: ' + fmtDate(d.date), left, y); y += 5.5;\n      doc.text('Locatie: ' + (d.location || 'Nog te bepalen'), left, y); y += 5.5;\n      doc.text('Aantal gasten: ' + d.guests, left, y); y += 9;\n\n      doc.setFont('helvetica', 'bold');\n      doc.text('Omschrijving', left, y);\n      doc.text('Bedrag', 165, y);\n      y += 5;\n      doc.setDrawColor(220);\n      doc.line(left, y, right, y);\n      y += 6;\n\n      const rows = [\n        [`${d.packageName} \u2014 ${currency.format(d.packagePrice)} p.p. x ${d.guests}`, d.packageTotal],\n        ...d.extras.map(x => [x.name, x.total]),\n        ['Logistiek \/ transport', d.logistics]\n      ];\n\n      doc.setFont('helvetica', 'normal');\n      rows.forEach(([label, amount]) => {\n        const lines = doc.splitTextToSize(label, 135);\n        doc.text(lines, left, y);\n        doc.text(currency.format(amount), right, y, { align: 'right' });\n        y += Math.max(6, lines.length * 5);\n      });\n\n      y += 3;\n      doc.line(120, y, right, y);\n      y += 7;\n\n      doc.text('Subtotaal excl. btw', 125, y);\n      doc.text(currency.format(d.subtotal), right, y, { align: 'right' });\n      y += 6;\n\n      doc.text('Btw 9%', 125, y);\n      doc.text(currency.format(d.vat), right, y, { align: 'right' });\n      y += 8;\n\n      doc.setFont('helvetica', 'bold');\n      doc.setFontSize(13);\n      doc.text('Totaal incl. btw', 125, y);\n      doc.text(currency.format(d.grand), right, y, { align: 'right' });\n\n      if (d.notes) {\n        y += 16;\n        if (y > 245) {\n          doc.addPage();\n          y = 20;\n        }\n        doc.setFontSize(11);\n        doc.text('Opmerkingen', left, y);\n        y += 7;\n        doc.setFont('helvetica', 'normal');\n        doc.setFontSize(10);\n        const noteLines = doc.splitTextToSize(d.notes, 170);\n        doc.text(noteLines, left, y);\n      }\n\n      doc.setFont('helvetica', 'normal');\n      doc.setFontSize(8.5);\n      doc.setTextColor(100);\n      doc.text(\n        'Deze offerte is een automatisch gegenereerde prijsindicatie en is 14 dagen geldig.',\n        left,\n        282\n      );\n      doc.text(\n        'Definitieve beschikbaarheid en maatwerk worden na aanvraag bevestigd.',\n        left,\n        287\n      );\n\n      const safeName = (d.company || d.name || 'catering').replace(\/[^a-z0-9-_]+\/gi, '-').replace(\/^-|-$\/g, '');\n      doc.save(`offerte-${safeName}.pdf`);\n    }\n\n    document.querySelectorAll('input, select, textarea').forEach(el => {\n      el.addEventListener('input', update);\n      el.addEventListener('change', update);\n    });\n\n    $('downloadBtn').addEventListener('click', downloadPDF);\n    $('resetBtn').addEventListener('click', () => {\n      document.querySelectorAll('input').forEach(el => {\n        if (el.type === 'checkbox') el.checked = false;\n        else if (el.id === 'guests') el.value = 50;\n        else el.value = '';\n      });\n      $('package').value = '42.50';\n      $('location').value = '';\n      $('notes').value = '';\n      $('notice').style.display = 'none';\n      update();\n    });\n\n    update();\n  <\/script>\n<\/body>\n<\/html>\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t","protected":false},"excerpt":{"rendered":"<p>Catering Offerte Generator Catering offerte generator Voorbeeld van een eenvoudige self-service offerteflow. De bezoeker vult de aanvraag in, ziet direct een prijsindicatie en kan vervolgens een nette PDF-offerte downloaden. 1. Stel je catering samen Klantgegevens Naam Bedrijfsnaam E-mail Telefoon Evenement Datum Aantal personen Cateringpakket Lunch basis \u2014 \u20ac 19,50 p.p.Lunch deluxe \u2014 \u20ac 27,50 p.p.Borrel [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"footnotes":""},"class_list":["post-9","page","type-page","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/offerte.bizzbetter.nl\/index.php?rest_route=\/wp\/v2\/pages\/9","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/offerte.bizzbetter.nl\/index.php?rest_route=\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/offerte.bizzbetter.nl\/index.php?rest_route=\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/offerte.bizzbetter.nl\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/offerte.bizzbetter.nl\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=9"}],"version-history":[{"count":4,"href":"https:\/\/offerte.bizzbetter.nl\/index.php?rest_route=\/wp\/v2\/pages\/9\/revisions"}],"predecessor-version":[{"id":13,"href":"https:\/\/offerte.bizzbetter.nl\/index.php?rest_route=\/wp\/v2\/pages\/9\/revisions\/13"}],"wp:attachment":[{"href":"https:\/\/offerte.bizzbetter.nl\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=9"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}