{"id":5707,"date":"2025-02-03T13:09:07","date_gmt":"2025-02-03T13:09:07","guid":{"rendered":"https:\/\/www.drenthecampings.nl\/?page_id=5707"},"modified":"2025-10-16T08:36:18","modified_gmt":"2025-10-16T08:36:18","slug":"campingplatz-mit-privaten-sanitaeranlagen-in-drenthe","status":"publish","type":"page","link":"https:\/\/www.drenthecampings.nl\/de\/camping\/campingplatz-mit-privaten-sanitaeranlagen-in-drenthe\/","title":{"rendered":"Campingplatz mit privaten Sanit\u00e4ranlagen in Drenthe"},"content":{"rendered":"<style type=\"text\/css\">\n    .header-heights {\n        height: 70vh;\n    }\n    .header-heights.home {\n        height: 80vh;\n    }\n    @media (max-width: 767px) {\n        .header-heights {\n            height: 80vh;\n        }\n        .header-heights.home {\n            height: 80vh;\n        }\n    }\n<\/style><section class=\"header-img\">\n        <div class=\"img-inner header-heights\" style=\"background-image: url(https:\/\/www.drenthecampings.nl\/wp-content\/uploads\/2024\/11\/20210728_100824-1600x1200.avif);\"><div class=\"container\"><div class=\"zb-search-seperate\">\n<!-- ZB INCLUDE -->\n<div class=\"col12\">\n<script type=\"text\/javascript\">\n    var ajaxurl = \"https:\/\/www.drenthecampings.nl\/wp-admin\/admin-ajax.php\";\n<\/script>\n\n<!-- Include jQuery UI CSS and JS if not already enqueued -->\n<link rel=\"stylesheet\" href=\"\/\/code.jquery.com\/ui\/1.12.1\/themes\/base\/jquery-ui.css\">\n<script src=\"\/\/code.jquery.com\/ui\/1.12.1\/jquery-ui.js\"><\/script>\n<script>\n  (function($){\n    var dcLang = \"de\";\n\n    if (dcLang === 'de') {\n      $.datepicker.regional['custom'] = {\n        closeText: 'Schliessen',\n        prevText: '\u2190',\n        nextText: '\u2192',\n        currentText: 'Heute',\n        monthNames: ['Januar','Februar','Marz','April','Mai','Juni',\n          'Juli','August','September','Oktober','November','Dezember'],\n        monthNamesShort: ['Jan','Feb','Mar','Apr','Mai','Jun','Jul','Aug','Sep','Okt','Nov','Dez'],\n        dayNames: ['Sonntag','Montag','Dienstag','Mittwoch','Donnerstag','Freitag','Samstag'],\n        dayNamesShort: ['So','Mo','Di','Mi','Do','Fr','Sa'],\n        dayNamesMin: ['So','Mo','Di','Mi','Do','Fr','Sa'],\n        weekHeader: 'KW',\n        dateFormat: 'dd-mm-yy',\n        firstDay: 1,\n        isRTL: false\n      };\n    } else {\n      $.datepicker.regional['custom'] = {\n        closeText: 'Sluiten',\n        prevText: '\u2190',\n        nextText: '\u2192',\n        currentText: 'Vandaag',\n        monthNames: ['januari','februari','maart','april','mei','juni',\n          'juli','augustus','september','oktober','november','december'],\n        monthNamesShort: ['jan','feb','mrt','apr','mei','jun','jul','aug','sep','okt','nov','dec'],\n        dayNames: ['zondag','maandag','dinsdag','woensdag','donderdag','vrijdag','zaterdag'],\n        dayNamesShort: ['zo','ma','di','wo','do','vr','za'],\n        dayNamesMin: ['Zo','Ma','Di','Wo','Do','Vr','Za'],\n        weekHeader: 'Wk',\n        dateFormat: 'dd-mm-yy',\n        firstDay: 1,\n        isRTL: false\n      };\n    }\n\n    $.datepicker.setDefaults($.datepicker.regional['custom']);\n  })(jQuery);\n<\/script>\n<script type=\"text\/javascript\">\n    var searchMode = 'guten_zb_search'; \/\/ \"camping-single\", \"guten_zb_result\", or \"guten_zb_search\"\n    var homepageResultsPage = 'https:\/\/www.drenthecampings.nl\/zoekresultaten\/';\n    console.log('searchMode:', searchMode);\n    console.log('homepageResultsPage:', homepageResultsPage);\n<\/script>\n\n<script>console.log(\"DC Debug \\u2014 max kamperen: 8, max huren: 10\");<\/script><script>var maxKamperen = 8;var maxHuren    = 10;<\/script>\n\n\n<!-- Search Bar Markup -->\n<div class=\"search-bar zb-search\">\n  <form id=\"search-form\" class=\"zb-form\">\n    <!-- 1. Pulldown for Kamperen\/Huren -->\n    <div class=\"zb-type zb-fields\">\n        <label for=\"acco-type\">Wie m\u00f6chten Sie \u00fcbernachten?<\/label>\n        <select id=\"acco-type\" name=\"acco_type_choice\">\n          <option value=\"kamperen\">Campen<\/option>\n          <option value=\"huren\">Mieten<\/option>\n        <\/select>\n    <\/div>\n\n    <!-- 2. Field for \"Wie gaat er mee\" with plus\/minus buttons -->\n    <div class=\"zb-persons zb-fields\">\n        <label for=\"persons-count\">Wer kommt mit?<\/label>\n        <div class=\"persons-field\">\n          <button class=\"btn\" type=\"button\" id=\"decrease-persons\">&#8211;<\/button>\n          <input type=\"number\" id=\"persons-count\" name=\"persons_count\" value=\"1\" min=\"1\" max=\"8\">\n          <button class=\"btn\" type=\"button\" id=\"increase-persons\">+<\/button>\n        <\/div>\n    <\/div>\n\n    <div class=\"zb-date zb-fields\">\n      <div class=\"startdate\">\n        <!-- 3. Arrival date field (read-only to force use of our custom datepicker) -->\n        <label for=\"arrival-date\">Ankunft:<\/label>\n        <input type=\"text\" id=\"arrival-date\" name=\"arrival_date\" readonly>\n        <img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/www.drenthecampings.nl\/wp-admin\/images\/loading.gif\" alt=\"Loading\" width=\"16\" height=\"16\" class=\"spinner\" style=\"display:none;\" \/>\n      <\/div>\n      <div class=\"enddate\">\n        <!-- 4. Departure date field (hidden by default) -->\n        <label for=\"departure-date\" id=\"departure-label\">Abreise:<\/label>\n        <input type=\"text\" id=\"departure-date\" name=\"departure_date\" readonly>\n      <\/div>\n    <\/div>\n    <!-- Hidden field for supplier ID -->\n    <input type=\"hidden\" id=\"supplier-id\" name=\"supplier_id\" value=\"\">\n    <input type=\"hidden\" id=\"camping-name\" value=\"Campingplatz mit privaten Sanit\u00e4ranlagen in Drenthe\">\n    <!-- 5. Search button -->\n    <button type=\"button\" class=\"btn zb-search-btn zb-btn\" id=\"search-button\">Suchen<\/button>\n  <\/form>\n  \n\n<\/div>\n<!-- Container for debug output (for testing purposes) \n<div style=\"background:white;\"id=\"debug-output\"><\/div>-->\n\n<!-- Container for final search results -->\n<a href=\"#\" class=\"btn results-open-filters\">Filter anzeigen<\/a>\n<div id=\"results-container\" class=\"zb-results\"><\/div>\n\n<script type=\"text\/javascript\">\n\n\/\/ ---------- date format converters ----------\nfunction isoToDutch(iso) {\n    if (!iso) return '';\n    var p = iso.split('-');\n    return (p[2] || '') + '-' + (p[1] || '') + '-' + (p[0] || '');\n}\nfunction dutchToIso(dutch) {\n    if (!dutch) return '';\n    var p = dutch.split('-');\n    return (p[2] || '') + '-' + (p[1] || '') + '-' + (p[0] || '');\n}\n\/\/ ---------- end converters ----------\n\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/ COOOOOOKIE\n\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/ COOOOOOKIE\n\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/ COOOOOOKIE\n\/\/ \u2500\u2500\u2500 Cookie helpers \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nfunction setCookie(name, value, days) {\n    console.log('setCookie() Called');\n    var expires = \"\";\n    if (days) {\n        var d = new Date();\n        d.setTime(d.getTime() + days*24*60*60*1000);\n        expires = \"; expires=\" + d.toUTCString();\n    }\n    document.cookie = name + \"=\" + encodeURIComponent(value || \"\") + expires + \"; path=\/\";\n}\nfunction getCookie(name) {\n    console.log('getCookie() Called');\n    return document.cookie.split('; ').reduce(function(r, v) {\n        var parts = v.split('=');\n        return parts[0] === name ? decodeURIComponent(parts[1]) : r;\n    }, null);\n}\n\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/ COOOOOOKIE END\n\n\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/ DATE HELPER \/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\nfunction forceDatepickerMonth($input, isoDate) {\n  if (!isoDate) return;\n  var keepVal = $input.val(); \/\/ \u2705 preserve what user selected\n  try {\n    var dt = $.datepicker.parseDate('yy-mm-dd', isoDate);\n    $input.datepicker('option', 'defaultDate', dt);\n    $input.datepicker('setDate', dt);  \/\/ forces drawMonth\/drawYear\n    $input.val(keepVal);               \/\/ \u2705 restore value (prevents overwriting)\n  } catch(e) {}\n}\n\njQuery(document).ready(function($) {\n    \/\/ \u2500\u2500\u2500 Prefill from cookie if present \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n    var raw   = getCookie('dc_search'),\n        prefs = raw ? JSON.parse(raw) : null;\n\n      \/\/ \u2500\u2500\u2500 ignore stale cookies \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n      if ( prefs && prefs.arrival ) {\n        \/\/ normalize to midnight today\n        var today     = new Date();\n        today.setHours(0,0,0,0);\n\n        \/\/ cookie stores arrival as \"YYYY-MM-DD\"\n        var arrDate   = new Date( prefs.arrival + 'T00:00:00' );\n        if ( arrDate < today ) {\n          \/\/ arrival is in the past \u2192 abandon cookie\n          prefs = null;\n        }\n      }\n\nif (prefs) {\n  \/\/ 1) Set type\/persons WITHOUT triggering change (avoid async race)\n  $('#acco-type').val(prefs.type);\n\/\/ \u2705 ensure sidebar filters match the cookie type (huren\/kamperen)\nif (typeof window.updateAccomFiltersVisibility === 'function') {\n  window.updateAccomFiltersVisibility();\n}\n  \/\/ clamp persons based on selected type\n  var maxP = getCurrentMax();\n  prefs.persons = Math.min(Math.max(parseInt(prefs.persons,10) || 1, 1), maxP);\n  $('#persons-count').val(prefs.persons).attr('max', maxP);\n\n  \/\/ 2) Set cookie dates into inputs\n  $('#arrival-date').val(isoToDutch(prefs.arrival));\n  $('#departure-date').val(isoToDutch(prefs.departure));\n\n  \/\/ 3) NOW fetch availability for THIS camping (supplier_id) and validate\nfetchAvailabilityData(function () {\n\n  var isoArr = prefs.arrival;\n  var isoDep = prefs.departure;\n\n\n  if (isCookieRangeValid(isoArr, isoDep)) {\n    \/\/ \u2705 keep cookie arrival\/departure exactly as-is\n\n    \/\/ Build allowed departure dates from durations\n    var durations = (availabilityData[isoArr] || [])\n      .slice()\n      .map(Number)\n      .filter(d => d >= 1 && d <= 21)\n      .sort((a,b)=>a-b);\n\n    var allowedDeps = durations.map(days => {\n      var parts = isoArr.split('-').map(Number);\n      var dt = new Date(parts[0], parts[1]-1, parts[2] + days);\n      return $.datepicker.formatDate('yy-mm-dd', dt);\n    });\n\n    \/\/ init departure picker (no auto-open)\n    initDepartureDatepicker(\n      $.datepicker.parseDate('yy-mm-dd', isoArr),\n      allowedDeps,\n      false\n    );\n\n    \/\/ keep cookie dep (it\u2019s valid), just persist once\n    updateSearchCookie();\n  } else {\n    \/\/ \u2757 only now do we auto-correct\n    applyDateValidation();\n  }\n\n  if (searchMode === 'camping-single' || searchMode === 'guten_zb_result') {\n    setTimeout(function(){ $('#search-button').trigger('click'); }, 0);\n  }\n});\n}\n\nelse {\n  \/\/ No cookie \u2192 first-available fallback using the same logic everywhere\n  fetchAvailabilityData(function () {\n    \/\/ arrival-date is empty, so applyDateValidation() will choose first available date\n    applyDateValidation();\n\n    if (searchMode === 'camping-single' || searchMode === 'guten_zb_result') {\n      setTimeout(function(){ $('#search-button').trigger('click'); }, 0);\n    }\n  });\n}\n\n    \/\/ \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n  \/\/ --- Helper Functions ---\n    \/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/ DISABLE FILTERS \/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\n    \/\/ Initially disable the filters.\n    $('.filters-section').addClass('filterblock-disabled');\n\n    function updateFilterAvailability() {\n      console.log(\"updateFilterAvailability() called\");\n\n      \/\/ 1) Start with the intended container\n      var $root = jQuery('#results-container');\n\n      \/\/ 2) If it doesn't contain results, find the zb-results that DOES\n      if (!$root.find('.accommodation-item, .camping-item').length) {\n        $root = jQuery('.zb-results:has(.accommodation-item, .camping-item)').first();\n      }\n\n      \/\/ 3) If still nothing, fall back to global (last resort)\n      var accoCount    = $root.find('.accommodation-item').length;\n      var campingCount = $root.find('.camping-item').length;\n\n      if (!accoCount && !campingCount) {\n        accoCount    = jQuery('.accommodation-item').length;\n        campingCount = jQuery('.camping-item').length;\n      }\n\n      console.log(\"Using root:\", $root.get(0));\n      console.log(\"Found\", accoCount, \"accommodation items and\", campingCount, \"camping items\");\n\n      if (accoCount > 0 || campingCount > 0) {\n        console.log(\"Enabling filters\");\n        jQuery('.filters-section').removeClass('filterblock-disabled');\n\n        if (typeof window.updateFilterCounts === \"function\") {\n          window.updateFilterCounts();\n        }\n      } else {\n        console.log(\"Disabling filters\");\n        jQuery('.filters-section').addClass('filterblock-disabled');\n      }\n    }\n\n\n\n    \/\/ Suppose you call updateFilterAvailability() when results load:\n    updateFilterAvailability();\n\n    \/\/ You might also want to call updateFilterAvailability() after an AJAX call finishes, etc.\n\n\n  \n  \/\/ Clear dates and destroy any open datepickers.\nfunction clearDates() {\n    console.log(\"clearDates() called\");\n    console.log(\"Before clearDates, #arrival-date has datepicker:\", $('#arrival-date').hasClass('hasDatepicker'));\n    $('#arrival-date').val('');\n    $('#departure-date').val('');\n    if ($('#arrival-date').hasClass('hasDatepicker')) {\n        console.log(\"Hiding datepicker for #arrival-date in clearDates\");\n        try {\n           $('#arrival-date').datepicker('hide');\n        } catch(e) { console.error(\"Error hiding #arrival-date:\", e); }\n        console.log(\"Destroying datepicker for #arrival-date in clearDates\");\n        try {\n           $('#arrival-date').datepicker('destroy');\n        } catch(e) { console.error(\"Error destroying #arrival-date:\", e); }\n    } else {\n        console.log(\"#arrival-date does not have a datepicker in clearDates\");\n    }\n    if ($('#departure-date').hasClass('hasDatepicker')) {\n        console.log(\"Hiding datepicker for #departure-date in clearDates\");\n        try {\n           $('#departure-date').datepicker('hide');\n        } catch(e) { console.error(\"Error hiding #departure-date:\", e); }\n        console.log(\"Destroying datepicker for #departure-date in clearDates\");\n        try {\n           $('#departure-date').datepicker('destroy');\n        } catch(e) { console.error(\"Error destroying #departure-date:\", e); }\n    } else {\n        console.log(\"#departure-date does not have a datepicker in clearDates\");\n    }\n    availabilityData = {};\n    \/\/validDepartureDates = [];\n    searchDataLoaded = false; \/\/ Reset flag.\n    \/\/$('#debug-output').empty();\n    console.log(\"After clearDates, #arrival-date has datepicker:\", $('#arrival-date').hasClass('hasDatepicker'));\n}\n\n\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/ COOKIE FUNCTION \/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\nfunction updateSearchCookie() {\n    console.log('updateSearchCookie() Called');\n  \/\/ 1) read the old cookie (or {} if none)\n  var raw  = getCookie('dc_search'),\n      data = raw ? JSON.parse(raw) : {};\n\n  \/\/ 2) merge in just the search fields\n  data.type      = $('#acco-type').val();\n  data.persons   = $('#persons-count').val();\n  data.arrival   = dutchToIso($('#arrival-date').val());\n  data.departure = dutchToIso($('#departure-date').val());\n\n  \/\/ 3) write it back\n  setCookie('dc_search', JSON.stringify(data), 7);\n}\n\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/ COOKIE FUNCTION END \/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\n\n\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/ FUNCTIE RECALL DATA API DUBBLE CHECK \/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\n\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/ FUNCTIE RECALL DATA API DUBBLE CHECK \/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\n\/**\n * Ensure the current arrival\/departure in the inputs is valid\n * for the current type & persons. If not, pick the first avail date.\n *\/\n\/\/ called when type\/persons change\nfunction ensureValidDates() {\n  console.log('ensureValidDates() Called');\n\n  \/\/ Keep what the user already picked\n  var currentArrIso = dutchToIso($('#arrival-date').val());\n  var currentDepIso = dutchToIso($('#departure-date').val());\n\n  fetchAvailabilityData(function () {\n\n    \/\/ \u2705 If current arrival still exists for this persons\/type \u2192 KEEP IT\n    var durations = (availabilityData[currentArrIso] || [])\n      .slice()\n      .map(Number)\n      .filter(d => d >= 1 && d <= 21)\n      .sort((a,b)=>a-b);\n\n    if (currentArrIso && durations.length) {\n\n      \/\/ Build allowed departures for this arrival\n      var parts = currentArrIso.split('-').map(Number);\n      var allowedDeps = durations.map(days => {\n        var dt = new Date(parts[0], parts[1]-1, parts[2] + days);\n        return $.datepicker.formatDate('yy-mm-dd', dt);\n      });\n\n      \/\/ Re-init departure picker for this arrival (don\u2019t auto-open)\n      initDepartureDatepicker(\n        $.datepicker.parseDate('yy-mm-dd', currentArrIso),\n        allowedDeps,\n        false\n      );\n\n      \/\/ \u2705 If current departure is still allowed \u2192 keep it\n      if (currentDepIso && allowedDeps.indexOf(currentDepIso) !== -1) {\n        \/\/ keep as-is\n      } else {\n        \/\/ otherwise snap to first allowed departure (shortest stay)\n        if (allowedDeps.length) {\n          $('#departure-date').val(isoToDutch(allowedDeps[0]));\n          currentDepIso = allowedDeps[0];\n        } else {\n          $('#departure-date').val('');\n        }\n      }\n\n      \/\/ Make departure calendar open on the right month (without changing value)\n      if (currentDepIso) {\n        forceDatepickerMonth($('#departure-date'), currentDepIso);\n      }\n\n      updateSearchCookie();\n      return; \/\/ \u2705 important: don't run applyDateValidation()\n    }\n\n    \/\/ \u2757 Only if arrival is NOT available anymore \u2192 pick first available\n    applyDateValidation();\n  });\n}\n\/\/\/\/\/\/\/\/\/\/\/\/ VALID COOKEI CHECKER \/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\n\/\/\/\/\/\/\/\/\/\/\/\/ VALID COOKEI CHECKER \/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\n\/\/\/\/\/\/\/\/\/\/\/\/ VALID COOKEI CHECKER \/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\nfunction isCookieRangeValid(isoArr, isoDep) {\n  if (!isoArr || !isoDep) return false;\n\n  \/\/ must exist in availability\n  var durs = (availabilityData[isoArr] || [])\n    .slice()\n    .map(Number)\n    .filter(d => d >= 1 && d <= 21);\n\n  if (!durs.length) return false;\n\n  \/\/ nights between cookie dates\n  var nights = Math.max(1, Math.round((new Date(isoDep) - new Date(isoArr)) \/ 86400000));\n  return durs.indexOf(nights) !== -1;\n}\n\n\/\/ the old inner logic of ensureValidDates\nfunction applyDateValidation() {\n  console.log('applyDateValidation() Called');\n\n  \/\/ 1\ufe0f\u20e3 read current arrival + lookup durations\n  const dutchArr = $(\"#arrival-date\").val();\n  const isoArr   = dutchToIso(dutchArr);                             \/\/ \"yyyy-mm-dd\"\n  const durations = (availabilityData[isoArr] || [])\n  .slice()\n  .map(Number)\n  .filter(d => d >= 1 && d <= 21)\n  .sort((a,b)=>a-b);\n\n  if (durations.length) {\n    \/\/ sort shortest first\n    durations.sort((a,b) => a - b);\n\n    \/\/ \u25b6\ufe0f NEW: parse via y,m,d into a true local-midnight Date\n    const [y, m, d] = isoArr.split('-').map(Number);\n    const baseY = y, baseM = m-1, baseD = d;\n\n    \/\/ 2\ufe0f\u20e3 compute & set the very first departure\n    const firstDep = new Date(baseY, baseM, baseD + durations[0]);\n    const isoDep   = $.datepicker.formatDate('yy-mm-dd', firstDep);\n    $(\"#departure-date\").val( isoToDutch(isoDep) );\n\n    \/\/ 3\ufe0f\u20e3 build the full list of allowed departure\u2010dates\n    const allowedDeps = durations.map(days => {\n      const dt = new Date(baseY, baseM, baseD + days);\n      return $.datepicker.formatDate('yy-mm-dd', dt);\n    });\n\n    \/\/ 4\ufe0f\u20e3 re-init your departure picker\n    initDepartureDatepicker(\n      $.datepicker.parseDate('yy-mm-dd', isoArr),\n      allowedDeps,\n      false  \/\/ don't auto-open on re-init\n    );\n\n  } else {\n    \/\/ \u2014 unchanged fallback when no durations for that arrival \u2014\n    console.log('applyDateValidation() ELSE Called');\n    const dates = Object.keys(availabilityData).sort();\n    if (dates.length) {\n      const first  = dates[0],\n            ds     = availabilityData[first].slice().sort((a,b)=>a-b),\n            arrObj = $.datepicker.parseDate('yy-mm-dd', first);\n\n      $(\"#arrival-date\").val( isoToDutch(first) );\n\n      const depObj = new Date(arrObj.getTime() + ds[0]*86400000);\n      $(\"#departure-date\").val(\n        isoToDutch($.datepicker.formatDate('yy-mm-dd', depObj))\n      );\n\n      initDepartureDatepicker(\n        arrObj,\n        ds.map(d => {\n          const dd = new Date(arrObj.getTime());\n          dd.setDate(dd.getDate() + d);\n          return $.datepicker.formatDate('yy-mm-dd', dd);\n        }),\n        false\n      );\n    }\n  }\n\n  \/\/ 5\ufe0f\u20e3 persist to cookie\n  updateSearchCookie();\n}\n\n\n\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/ FUNCTIE RECALL DATA API DUBBLE CHECK END \/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\n\n\n  \/\/ --- Event Bindings for Fields ---  \n\/\/ helper to pick current max\n    function getCurrentMax() {\n        return $('#acco-type').val() === 'huren'\n            ? maxHuren\n            : maxKamperen;\n    }\n\n    \/\/ clamp on manual entry\n    $('#persons-count').on('input change', function() {\n        var maxP = getCurrentMax(),\n            val  = parseInt(this.value, 10) || 0;\n        if ( val > maxP ) {\n            console.log('DC Debug \u2014 entered above max, clamping to ' + maxP);\n            this.value = maxP;\n        }\n        if ( val < 1 ) {\n            this.value = 1;\n        }\n        \/\/clearDates();\n        updateSearchCookie();\n        ensureValidDates();\n    });\n\n    \/\/ \u201c+\u201d button\n    $('#increase-persons').off('click').on('click', function() {\n        var maxP  = getCurrentMax(),\n            count = parseInt($('#persons-count').val(), 10);\n        if ( count < maxP ) {\n            $('#persons-count').val(count + 1);\n        } else {\n            console.log('DC Debug \u2014 at type\u2010specific max (' + maxP + ')');\n            $('#persons-count').val(maxP);\n        }\n        \/\/clearDates();\n        updateSearchCookie();\n        ensureValidDates();\n    });\n\n    \/\/ \u201c\u2013\u201d button (unchanged)\n    $('#decrease-persons').off('click').on('click', function() {\n        var count = parseInt($('#persons-count').val(), 10);\n        if ( count > 1 ) {\n            $('#persons-count').val(count - 1);\n            \/\/clearDates();\n            updateSearchCookie();\n            ensureValidDates();\n        }\n    });\n\n    \/\/ when the type selector changes, update the <input>\u2019s max attribute\n    $('#acco-type').on('change', function() {\n        updateSearchCookie();\n        \/\/clearDates();\n\n        var maxP = getCurrentMax();\n        console.log('DC Debug \u2014 type changed, new max = ' + maxP);\n        $('#persons-count').attr('max', maxP);\n        \/\/ clamp current value if needed\n        if ( parseInt($('#persons-count').val(), 10) > maxP ) {\n            $('#persons-count').val(maxP);\n            \n            \n        }\n        updateSearchCookie();\n        ensureValidDates();\n    });\n\n  \/\/ --- Global Variables ---\nvar availabilityData = {};\nvar allDepartures    = [];\nvar searchDataLoaded = false;\nvar arrivalDates    = [];\n    \/\/ NEW: cache per \u201ctype_persons\u201d combo\n\n\nfunction initArrivalDatepicker() {\n    console.log(\"initArrivalDatepicker() called\");\n  \/\/ destroy any old\n  $('#arrival-date').datepicker('destroy');\n\n  $('#arrival-date').datepicker({\n    dateFormat: 'dd-mm-yy',\n\n\n    \/\/ only light\u2010up real start_dates\n    beforeShowDay: function(date) {\n      const iso = $.datepicker.formatDate('yy-mm-dd', date);\n      return arrivalDates.indexOf(iso) !== -1\n        ? [true, 'available', 'Available']\n        : [false, 'not-available', 'Not available'];\n    },\n\nonSelect: function(dutchDate) {\n  const isoDate = dutchToIso(dutchDate);\n  const durations = (availabilityData[isoDate] || [])\n  .slice()\n  .map(Number)\n  .filter(d => d >= 1 && d <= 21)   \/\/ \u2705 cap at 3 weeks\n  .sort((a,b)=>a-b);\n\n  \/\/ build allowed departure iso dates\n  const allowed = durations.map(days => {\n    const [y,m,d] = isoDate.split('-').map(Number);\n    const dt = new Date(y, m-1, d + days);\n    return $.datepicker.formatDate('yy-mm-dd', dt);\n  });\n\n  \/\/ rebuild departure picker for this arrival\n  initDepartureDatepicker(\n    $.datepicker.parseDate('yy-mm-dd', isoDate),\n    allowed,\n    true\n  );\n\n  \/\/ \u2705 if current departure is invalid for new arrival, snap to first allowed\n  var currentDepIso = dutchToIso($('#departure-date').val());\n  if (!currentDepIso || (allowed.length && allowed.indexOf(currentDepIso) === -1)) {\n    if (allowed.length) {\n      $('#departure-date').val( isoToDutch(allowed[0]) );\n    } else {\n      $('#departure-date').val('');\n    }\n  }\n\n  \/\/ \u2705 force departure calendar to show the right month (first allowed dep)\n  if (allowed.length) {\n    forceDatepickerMonth($('#departure-date'), allowed[0]);\n  }\n\n  updateSearchCookie();\n}\n      });\n\n      \/\/ \ud83d\udea9 Guard the \u201cshow\u201d call so we never ask a non-existent instance to show itself\n      if ( $('#arrival-date').hasClass('hasDatepicker') ) {\n        try {\n          $('#arrival-date').datepicker('show');\n        } catch (e) {\n          \/\/ if it\u2019s gone, swallow the error\n        }\n      }\n\n      $('.spinner').hide();\n    }\n\n\nfunction initDepartureDatepicker(arrivalDate, allowedDates, autoShow = true) {\n  $('#departure-date').datepicker('destroy');\n\n  $('#departure-date').datepicker({\n    dateFormat: 'dd-mm-yy',\n    minDate: arrivalDate,\n    beforeShowDay: function(date) {\n      var iso = $.datepicker.formatDate('yy-mm-dd', date);\n      return allowedDates.indexOf(iso) !== -1\n        ? [true, 'available', 'Available']\n        : [false, 'not-available', 'Not available'];\n    },\n    onSelect() { updateSearchCookie(); }\n  });\n\n  \/\/ \u2705 FORCE MONTH (fixes \"stuck on June\" after selecting Jan)\n  if (allowedDates && allowedDates.length) {\n    forceDatepickerMonth($('#departure-date'), allowedDates.slice().sort()[0]);\n  }\n\n  if (autoShow && $('#departure-date').hasClass('hasDatepicker')) {\n    setTimeout(() => {\n      try { $('#departure-date').datepicker('show'); } catch (e) {}\n    }, 100);\n  }\n}\n\n\n\n\nfunction fetchAvailabilityData(callback) {\n  console.log(\"fetchAvailabilityData() called\");\n\n  \/\/ 1\ufe0f\u20e3 Build our cache key\n  var accoType     = $('#acco-type').val();\n  var personsCount = $('#persons-count').val();\n  var cacheKey     = 'avail_' + accoType + '_' + personsCount;\n\n\n  \/\/ Determine if we\u2019re on the homepage (all campings) \u2192 only then use cache\n  var supplierId = (jQuery('#supplier-id').val() || '').trim();\n  var canCache   = !supplierId; \/\/ true only when no supplier_id present (homepage)\n\n  \/\/ 2\ufe0f\u20e3 Try to read from sessionStorage (homepage\/all-campings only)\n  if (canCache) {\n    var raw = sessionStorage.getItem(cacheKey);\n    if (raw) {\n      try {\n        var payload = JSON.parse(raw);\n        \/\/ TTL check: 10 minutes = 600,000 ms\n        if (Date.now() - payload.ts < 600000) {\n          console.log('Using cached availability for', cacheKey);\n          availabilityData = payload.data;\n          \/\/ recompute arrivals + departures\n          arrivalDates = Object.keys(availabilityData);\n          window.allDepartures = [];\n          arrivalDates.forEach(function(arrIso) {\n            var arrObj = $.datepicker.parseDate('yy-mm-dd', arrIso);\n            availabilityData[arrIso].forEach(function(days) {\n              var dep = new Date(arrObj);\n              dep.setDate(dep.getDate() + days);\n              var depIso = $.datepicker.formatDate('yy-mm-dd', dep);\n              if (!window.allDepartures.includes(depIso)) {\n                window.allDepartures.push(depIso);\n              }\n            });\n          });\n          searchDataLoaded = true;\n          if (typeof callback === 'function') callback();\n          return;  \/\/ skip AJAX entirely\n        } else {\n          \/\/ expired \u2192 remove it\n          sessionStorage.removeItem(cacheKey);\n        }\n      } catch(e) {\n        console.warn('Bad cache payload, clearing', cacheKey, e);\n        sessionStorage.removeItem(cacheKey);\n      }\n    }\n  }\n\n\n  \/\/ 3\ufe0f\u20e3 Not cached \u2192 do the AJAX\n  $('.spinner').show();\n  var today    = new Date(),\n      nextYear = new Date();\n  nextYear.setFullYear(today.getFullYear() + 1);\n\n  $.post(ajaxurl, {\n    action:        'search_availabilities',\n    acco_type:     accoType,\n    persons_count: personsCount,\n    supplier_id:   $('#supplier-id').val(),\n    start_date:    $.datepicker.formatDate('yy-mm-dd', today),\n    end_date:      $.datepicker.formatDate('yy-mm-dd', nextYear)\n  }, function(response) {\n    $('.spinner').hide();\n\n    \/\/ rebuild availabilityData\n    availabilityData = {};\n    $.each(response.data, function(_, details) {\n      (details.availabilities || []).forEach(function(av) {\n        var d   = av.start_date,\n            dur = parseInt(av.duration, 10);\n        availabilityData[d] = availabilityData[d] || [];\n        if (!availabilityData[d].includes(dur)) {\n          availabilityData[d].push(dur);\n        }\n      });\n    });\n\n    \/\/ recompute arrivalDates + allDepartures\n    arrivalDates = Object.keys(availabilityData);\n    window.allDepartures = [];\n    arrivalDates.forEach(function(arrIso) {\n      var arrObj = $.datepicker.parseDate('yy-mm-dd', arrIso);\n      availabilityData[arrIso].forEach(function(days) {\n        var dep = new Date(arrObj);\n        dep.setDate(dep.getDate() + days);\n        var depIso = $.datepicker.formatDate('yy-mm-dd', dep);\n        if (!window.allDepartures.includes(depIso)) {\n          window.allDepartures.push(depIso);\n        }\n      });\n    });\n\n    if (canCache) {\n      sessionStorage.setItem(cacheKey, JSON.stringify({\n        ts:   Date.now(),\n        data: availabilityData\n      }));\n    }\n\n\n    searchDataLoaded = true;\n    if (typeof callback === 'function') callback();\n  }, 'json')\n  .fail(function(jqXHR, textStatus) {\n    $('.spinner').hide();\n    console.error('fetchAvailabilityData error:', textStatus);\n  });\n}\n\n\n\n\n  \/\/ --- Event Binding for Arrival Field ---\n    \n$('#arrival-date').on('click', function(e) {\n  e.preventDefault();\n  $('.spinner').show();\n  updateSearchCookie();\n\n  if (!searchDataLoaded) {\n    fetchAvailabilityData(initArrivalDatepicker);\n  } else {\n    \/\/ first hide any currently-visible calendar\n    if ($.datepicker._curInst) {\n      $.datepicker._hideDatepicker();\n    }\n    \/\/ then safely rebuild &#038; show it\n    initArrivalDatepicker();\n  }\n});\n\n\n\n  \/\/ --- Search Button Click Handler ---\n  \n  $('body').on('click', '#search-button', function(e) {\n      updateSearchCookie();\n      e.preventDefault();\n      \/\/$('#debug-output').empty();\n\n\n      var accoType = $('#acco-type').val();\n      var personsCount = $('#persons-count').val();\n      var supplierId = $('#supplier-id').val();\n      var arrivalDate   = dutchToIso( $('#arrival-date').val() );\n      var departureDate = dutchToIso( $('#departure-date').val() );\n\n      if (!arrivalDate || !departureDate) {\n          alert(\"Please select both arrival and departure dates.\");\n          return;\n      }\n      \n      \/\/ If mode is either camping-single or guten_zb_result, perform inline AJAX search.\n      if (searchMode === 'camping-single' || searchMode === 'guten_zb_result') {\n          var data = {\n              action: 'final_search_availabilities',\n              acco_type: accoType,\n              persons_count: personsCount,\n              supplier_id: supplierId,\n              arrival_date: arrivalDate,\n              departure_date: departureDate,\n              search_mode: searchMode  \/\/ This will be \"guten_zb_result\" on the overview page.\n          };\n\n          $('#results-container').html('<p><img decoding=\"async\" src=\"https:\/\/www.drenthecampings.nl\/wp-admin\/images\/loading.gif\" alt=\"Loading...\"> Zoeken naar accommodaties\u2026<\/p>');\n\n          $.post(ajaxurl, data, function(response) {\n              $('#results-container').html(response);\n\n          console.log(\"Search results loaded; calling updateFilterAvailability()\");\n          updateFilterAvailability();\n  \/\/ \u2705 refresh \u201cType accommodatie\u201d baseline counts after results exist\n  if (typeof window.dcRefreshAccoTypeCounts === 'function') {\n    window.dcRefreshAccoTypeCounts();\n  }\n          \/\/\/\/\/\/\/\/\/\/\/ RANDOM ORDER IEDERE DAG!!!!!!! \/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\n          \/\/\/\/\/\/\/\/\/\/\/ RANDOM ORDER IEDERE DAG!!!!!!! \/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\n          \/\/\/\/\/\/\/\/\/\/\/ RANDOM ORDER IEDERE DAG!!!!!!! \/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\n            \/\/ \u2014\u2014\u2014 seeded PRNG (Mulberry32) \u2014\u2014\u2014\n            function mulberry32(a) {\n                return function() {\n                    a |= 0;\n                    a = a + 0x6D2B79F5 | 0;\n                    var t = Math.imul(a ^ a >>> 15, 1 | a);\n                    t = t + Math.imul(t ^ t >>> 7, 61 | t) ^ t;\n                    return ((t ^ t >>> 14) >>> 0) \/ 4294967296;\n                };\n            }\n\n            \/\/ \u2014\u2014\u2014 in-place Fisher\u2013Yates using our PRNG \u2014\u2014\u2014\n            function seededShuffle(arr, randomFn) {\n                var m = arr.length,\n                    t, i;\n                while (m) {\n                    i = Math.floor(randomFn() * m--);\n                    t = arr[m];\n                    arr[m] = arr[i];\n                    arr[i] = t;\n                }\n                return arr;\n            }\n\n            $(function() {\n                \/\/ 1) build today\u2019s seed\n                var d = new Date(),\n                    seed = Number([\n                        d.getFullYear(),\n                        String(d.getMonth() + 1).padStart(2, '0'),\n                        String(d.getDate()).padStart(2, '0')\n                    ].join(''));\n                var rand = mulberry32(seed);\n\n                \/\/ 2) point at your UL, not the whole div\n                var $list = $('#results-container > ul.camping-list'),\n                    blocks = [];\n\n                \/\/ 3) walk its children and slice out [group,item,acco] triples\n                var $kids = $list.children();\n                for (var i = 0; i < $kids.length; i++) {\n                    if ($kids.eq(i).hasClass('camping-group')) {\n                        var $g = $kids.eq(i),\n                            $it = $kids.eq(i + 1),\n                            $ac = $kids.eq(i + 2);\n                        blocks.push([$g, $it, $ac]);\n                        i += 2;\n                    }\n                }\n\n                \/\/ 4) shuffle and re-append _only_ those triples\n                seededShuffle(blocks, rand);\n                $list.empty();\n                blocks.forEach(function(triple) {\n                    $list.append(triple[0], triple[1], triple[2]);\n                });\n\n                \/\/ \u2026now your price-loader \u201c.each\u201d can run on the new order\u2026\n            });\n\n        \/\/\/\/\/\/\/\/\/\/\/ RANDOM ORDER IEDERE DAG!!!!!!! END \/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\n\n        \/\/\/\/\/\/\/\/\/\/\/ storage cache price helper \/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\n\n        function renderAccommodationPrice($ph, html) {\n          \/\/ 1) inject the price\u2010details HTML\n          $ph.html(html);\n\n          \/\/ 2) pull out the \u20acXX,XX total\n          const totalText = $ph\n            .find('table.h-price-table tr.h-price-total td')\n            .text().trim();\n\n          \/\/ 3) convert to a number\n          const numeric = parseFloat(\n            totalText.replace(\/[^0-9,]\/g,'').replace(',','.')\n          );\n\n          \/\/ 4) bubble up into the .camping-item immediately before\n          const $camping = $ph.closest('ul.accommodation-list').prev('li.camping-item');\n          if (!$camping.length) return;\n\n          const currentMin = $camping.data('minPrice')||Infinity;\n          if (numeric < currentMin) {\n            $camping\n              .data('minPrice', numeric)\n              .find('.camping-price')\n                .html('<span>Vanaf<\/span> ' + totalText)\n                .addClass('camping-price-calculated');\n          }\n        }\n\n        \/\/\/\/\/\/\/\/\/\/\/\/\/\/ end \/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\n        \/\/ Lazy load price details for each result.\n        \/\/\/\/\/\/\/ LOAD PRIJS OP CAMPING OVERVIEWWW\n        \/\/ Lazy load (and cache) price details for each result.\n       $('.price-placeholder.accommodation-price').each(function() {\n          const $ph      = $(this);\n          const prod     = $ph.data('product-id');\n          const nights   = $ph.data('nights');\n          const persons  = $ph.data('persons');\n          const basePrice= $ph.data('base-price');\n\n          const key = `price_${prod}_${nights}_${persons}`;\n          const raw = sessionStorage.getItem(key);\n\n          if (raw) {\n            try {\n              const payload = JSON.parse(raw);\n              \/\/ 15 min TTL  = 900 000 ms\n              if (Date.now() - payload.ts < 900000) {\n                console.log('\ud83d\uddc4\ufe0f using cached price for', key);\n                return renderAccommodationPrice($ph, payload.html);\n              } else {\n                sessionStorage.removeItem(key);\n              }\n            } catch(e) {\n              sessionStorage.removeItem(key);\n            }\n          }\n\n          \/\/ not cached \u2192 AJAX\n          $.post(ajaxurl, {\n            action: 'get_price_details',\n            product_id: prod,\n            nights: nights,\n            persons_count: persons,\n            base_price: basePrice\n          }, function(resp) {\n            \n            if (!resp.success) {\n              return $ph.text('Price details unavailable.');\n            }\n            \/\/ stash in sessionStorage\n            sessionStorage.setItem(key, JSON.stringify({\n              ts:   Date.now(),\n              html: resp.data.html\n            }));\n            renderAccommodationPrice($ph, resp.data.html);\n          }, 'json');\n        });\n\n\n\n      \/\/ Bind toggle event for price details.\n      \/\/ Toggle .price-details and add .open to .accommodation-item\n      \/\/ Toggle .price-details and add .open to .accommodation-item + toggle button\n\/\/ Toggle .price-details and add .open to .accommodation-item + toggle button\n$('#results-container')\n  .off('click', '.price-details-toggle')\n  .on('click', '.price-details-toggle', function(e) {\n    e.preventDefault();\n\n    let $toggle = $(this);\n    let $accommodationItem = $toggle.closest('.accommodation-item');\n    let $priceDetails = $accommodationItem.find('.price-details');\n\n    \/\/ Toggle open state\n    $priceDetails.toggleClass('open');\n    $accommodationItem.toggleClass('open');\n    $toggle.toggleClass('open');\n\n    \/\/ \u2705 Add\/remove helper class on the accommodation-list (if it exists)\n    let $list = $accommodationItem.closest('ul.accommodation-list');\n    if ($list.length) {\n      if ($priceDetails.hasClass('open')) {\n        $list.addClass('price-detail-open');\n      } else {\n        \/\/ only remove if no other price-details are open in this list\n        if (!$list.find('.price-details.open').length) {\n          $list.removeClass('price-detail-open');\n        }\n      }\n    }\n  });\n\n\/\/ Close when clicking outside\n$(document).on('click', function(e) {\n  if (!$(e.target).closest('.accommodation-item .price-details, .price-details-toggle').length) {\n    $('.accommodation-item .price-details').removeClass('open');\n    $('.accommodation-item').removeClass('open');\n    $('.price-details-toggle').removeClass('open');\n\n    \/\/ \u2705 also remove the list helper class everywhere\n    $('ul.accommodation-list').removeClass('price-detail-open');\n  }\n});\n\n      }).fail(function(jqXHR, textStatus, errorThrown) {\n              $('#results-container').html('<p>Error: ' + textStatus + '<\/p><pre>' + errorThrown + '<\/pre>');\n          });\n      } else if (searchMode === 'guten_zb_search') {\n          console.log(\"Search mode is guten_zb_search\");\n          \/\/ For legacy homepage mode that redirects.\n          window.location.href = homepageResultsPage;\n\n      }\n  });\n\/\/ Open filters from inside results container\n$('body').on('click', '.results-open-filters', function(e){\n  e.preventDefault();\n  $('.filters-section').addClass('open');\n  $('.overlay-shade').addClass('open');\n});\n\n\n\n});\n\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/ BOOKING OVERVIEW CLICK ADD COOKIE DETAILS \/\/\/\/\/\/\/\/\/\/\/\/\/\n\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/ BOOKING OVERVIEW CLICK ADD COOKIE DETAILS \/\/\/\/\/\/\/\/\/\/\/\/\/\n\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/ BOOKING OVERVIEW CLICK ADD COOKIE DETAILS \/\/\/\/\/\/\/\/\/\/\/\/\/\njQuery(document).on('click', '.btn-book-accommodation-card', function(e){\n  e.preventDefault();\n\n  var $btn     = jQuery(this),\n      href     = $btn.attr('href'),\n      prodId   = $btn.data('product-id'),\n      prodName = $btn.data('product-name');\n\n\/\/ \u2705 camping name: overview DOM first, then hidden field, then cookie fallback\nvar campingNameFromDom =\n  $btn.closest('li.accommodation-item')\n      .closest('ul.accommodation-list')\n      .prev('li.camping-item')\n      .find('h3')\n      .first()\n      .text()\n      .trim();\n\nvar campingNameFromHidden = jQuery('#camping-name').val() || '';\ncampingNameFromHidden = (campingNameFromHidden || '').trim();\n\n  \/\/ read cookie\n  var raw = getCookie('dc_search'),\n      obj = raw ? JSON.parse(raw) : {};\n\n  \/\/ write\n  obj.product_id   = prodId;\n  obj.product_name = prodName;\n  obj.camping_name = campingNameFromDom || campingNameFromHidden || obj.camping_name || '';\n\n  setCookie('dc_search', JSON.stringify(obj), 7);\n\n  \/\/ go\n  window.location.href = href;\n});\n\n\n\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/ Camping level overview jqeury \/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\n\/\/ Delegate the click event for the \"Toon Accommodaties\" button (btn-book-camping-card)\njQuery(document).on('click', '.btn-book-camping-card', function(e) {\n    e.preventDefault();\n    var $campingItem = jQuery(this).closest('li.camping-item');\n    var $accoList = $campingItem.next('ul.accommodation-list');\n    $accoList.toggleClass('open');\n    if ($accoList.hasClass('open')) {\n         \/\/ If open, append an overlay after the list if it doesn't already exist.\n         if ($accoList.next('.overlay-list').length === 0) {\n              $accoList.after('<div class=\"overlay-list\"><\/div>');\n         }\n    } else {\n         \/\/ If closed, remove any existing overlay.\n         $accoList.next('.overlay-list').remove();\n    }\n});\n\njQuery(document).on('click', '.close-acco-list', function(e) {\n    e.preventDefault();\n    var $accoList = jQuery(this).closest('ul.accommodation-list');\n    $accoList.removeClass('open');\n    \/\/ Remove the overlay as well.\n    $accoList.next('.overlay-list').remove();\n});\n\/\/ close when clicking on the overlay\njQuery(document).on('click', '.overlay-list', function(e) {\n  e.preventDefault();\n  var $accoList = jQuery(this).prev('ul.accommodation-list');\n  $accoList.removeClass('open');\n  jQuery(this).remove();\n});\n\n\n\n<\/script>\n<\/div>\n<!-- ZB INCLUDE END -->\n<\/div>\n<\/div><\/div><\/section>\n\n\n<h1 class=\"wp-block-heading\">Campingplatz mit privaten Sanit\u00e4ranlagen in Drenthe<\/h1>\n\n\n\n<p>Drenthe Campings, wo Sie Luxuscamping mit privaten Sanit\u00e4ranlagen genie\u00dfen k\u00f6nnen. Hier genie\u00dfen Sie das gewisse Extra an Komfort w\u00e4hrend eines wundersch\u00f6nen Campingurlaubs. Auf unseren Campingpl\u00e4tzen in Drenthe verf\u00fcgen Sie \u00fcber eigene Sanit\u00e4ranlagen auf Ihrem Stellplatz. Wie wunderbar ist es, im Toilettengeb\u00e4ude nicht anstehen zu m\u00fcssen? Keine Wege zum Toilettengeb\u00e4ude. Nein, es ist sch\u00f6n, im Urlaub immer alles griffbereit zu haben.<\/p>\n\n\n\n<p>Kommen Sie zum Campen auf einen unserer Campingpl\u00e4tze mit privaten Sanit\u00e4ranlagen und genie\u00dfen Sie einen luxuri\u00f6sen Campingurlaub!<\/p>\n\n\n<style type='text\/css'>\n        #tz-spacer-69f695ebcef8e {\n            \n        }\n    <\/style><div id='tz-spacer-69f695ebcef8e' class='tz-spacer'><\/div>\n\n<div style=\"margin-top: px\" class=\"tz-omenom-container image-left color-kleur1 mask  no-top-margin bottom-margin\"><div class=\"container\"><div class=\"col6 omenom-image\"><img loading=\"lazy\" decoding=\"async\" width=\"1200\" height=\"800\" src=\"https:\/\/www.drenthecampings.nl\/wp-content\/uploads\/2025\/01\/prive-sanitair-type-1-365B0DE66-6C68-8847-80BD-E5509F0C3BF4.avif\" class=\"attachment-large size-large\" alt=\"\" srcset=\"https:\/\/www.drenthecampings.nl\/wp-content\/uploads\/2025\/01\/prive-sanitair-type-1-365B0DE66-6C68-8847-80BD-E5509F0C3BF4.avif 1200w, https:\/\/www.drenthecampings.nl\/wp-content\/uploads\/2025\/01\/prive-sanitair-type-1-365B0DE66-6C68-8847-80BD-E5509F0C3BF4-750x500.avif 750w, https:\/\/www.drenthecampings.nl\/wp-content\/uploads\/2025\/01\/prive-sanitair-type-1-365B0DE66-6C68-8847-80BD-E5509F0C3BF4-768x512.avif 768w\" sizes=\"auto, (max-width: 1200px) 100vw, 1200px\" \/><\/div><div class=\"col4 omenom-content\"><h3>Was bedeutet Camping mit privaten Sanit\u00e4ranlagen in Drenthe?<\/h3><div class=\"omenom-editor\"><p>Camping bei Drenthe Campings auf einem Campingplatz von DrentheCampings Torentjeshoek11 mit privaten Sanit\u00e4ranlagen, das ist der Komfort, den jeder Camper sucht.<\/p>\n<ul>\n<li>Keine Warteschlangen vor dem Sanit\u00e4rgeb\u00e4ude<\/li>\n<li>Dusche, Toilette und Abwaschbereich immer griffbereit<\/li>\n<li>Luxuscamping mit privaten Sanit\u00e4ranlagen<\/li>\n<li>Nur f\u00fcr Sie und Ihre Reisebegleiter<\/li>\n<\/ul>\n<p>Verschiedene Campingpl\u00e4tze in Drenthe haben Holzeinheiten aufgestellt, sodass sich die Einheit in die waldreiche Umgebung einf\u00fcgt. Andere haben ein kleines Haus gebaut, ein Mini-Sanit\u00e4rgeb\u00e4ude. So oder so wird es zu Ihrem Urlaub beitragen.<\/p>\n<\/div><\/div><\/div><\/div>\n\n\n<div class=\"wp-block-columns is-style-default is-layout-flex wp-container-core-columns-is-layout-9d6595d7 wp-block-columns-is-layout-flex\">\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\">\n<h3 class=\"wp-block-heading\">H\u00e4ufig gestellte Fragen zu Drenthe-Campingpl\u00e4tzen mit privaten Sanit\u00e4ranlagen<\/h3>\n\n\n\n<div class=\"wp-block-tz-tabs accordion\">\n<div class=\"wp-block-tz-tab tab-item\"><h3 class=\"tab-header\">Entscheiden sich viele f\u00fcr einen Campingplatz mit Sanit\u00e4ranlagen?<\/h3><div class=\"tab-content-item\">\n<p>Ja, Camping mit privaten Sanit\u00e4ranlagen ist ein Wunsch vieler Urlauber. Es bietet genau das gewisse Extra an Luxus, das Ihrem Urlaub das gewisse Extra verleiht. Wir nennen das komfortables Camping.<\/p>\n<\/div><\/div>\n\n\n\n<div class=\"wp-block-tz-tab tab-item\"><h3 class=\"tab-header\">Verf\u00fcgen die Sanit\u00e4rkabinen \u00fcber eine Dusche?<\/h3><div class=\"tab-content-item\">\n<p>Ja, die meisten privaten Sanit\u00e4rkabinen verf\u00fcgen auch \u00fcber eine Dusche. Sie sind oft auch mit einer Heizung ausgestattet, was insbesondere in der Fr\u00fchlings- und Herbstsaison eine L\u00f6sung darstellt.<\/p>\n<\/div><\/div>\n\n\n\n<div class=\"wp-block-tz-tab tab-item\"><h3 class=\"tab-header\">Gibt es auch Sanit\u00e4ranlagen speziell f\u00fcr Camper?<\/h3><div class=\"tab-content-item\">\n<p>Ja, es gibt Campingpl\u00e4tze mit Carport f\u00fcr Wohnmobilstellpl\u00e4tze. Sie k\u00f6nnen beispielsweise zum Camping Meistershof in Drenthe gehen.<\/p>\n<\/div><\/div>\n\n\n\n<div class=\"wp-block-tz-tab tab-item\"><h3 class=\"tab-header\">Wo befinden sich die meisten Wohnmobilstellpl\u00e4tze?<\/h3><div class=\"tab-content-item\">\n<p>Drenthe-Campingpl\u00e4tze sind \u00fcber die ganze Provinz verteilt. Die privaten Sanit\u00e4ranlagen sind auf jedem Campingplatz unterschiedlich. Sie verf\u00fcgen alle \u00fcber eine Dusche, Toilette und ein Waschbecken, wo Sie auch das Geschirr sp\u00fclen k\u00f6nnen. Es gibt Campingpl\u00e4tze, die zus\u00e4tzlich \u00fcber eine Fu\u00dfbodenheizung, sowie eine Au\u00dfenk\u00fcche etc. verf\u00fcgen.<\/p>\n<\/div><\/div>\n<\/div>\n\n\n<style type='text\/css'>\n        #tz-spacer-69f695ebdaff8 {\n            \n        }\n    <\/style><div id='tz-spacer-69f695ebdaff8' class='tz-spacer'><\/div>\n\n\n<h3 class=\"wp-block-heading\">Finden Sie ganz einfach die Stellplatz mit privaten Sanit\u00e4ranlagen, die zu Ihnen passt<\/h3>\n\n\n\n<p>Noch nie war es so einfach, einen Urlaub zu finden und zu buchen!<\/p>\n\n\n  <div id=\"overviewlight_aaae3d79-28af-4981-9ba4-073a2e481025\" class=\"overviewlight-async\">\n    <div class=\"overviewlight-loader\" style=\"padding:20px;text-align:center;\">\n      <img decoding=\"async\" src=\"https:\/\/www.drenthecampings.nl\/wp-admin\/images\/loading.gif\" alt=\"Loading\" style=\"width:16px;height:16px;vertical-align:middle;\">\n      <span style=\"margin-left:8px;\">Laden\u2026<\/span>\n    <\/div>\n  <\/div>\n\n<script>\ndocument.addEventListener('DOMContentLoaded', function(){\n  var el = document.getElementById(\"overviewlight_aaae3d79-28af-4981-9ba4-073a2e481025\");\n  if (!el) return;\n\n  var data = new FormData();\n  data.append('action', 'zb_overview_light_render');\n  data.append('nonce', \"dec651ad1b\");\n  data.append('post_id', 5707);\n\n  var settings = {\"filter_groups\":[\"Camping faciliteiten\",\"Kampeerfaciliteiten\"],\"zb_light_filters\":[\"2344\"]};\n  data.append('settings', JSON.stringify(settings));\n\n  fetch(\"https:\\\/\\\/www.drenthecampings.nl\\\/wp-admin\\\/admin-ajax.php\", {\n    method: 'POST',\n    credentials: 'same-origin',\n    body: data\n  })\n  .then(function(r){ return r.json(); })\n  .then(function(resp){\n    if (!resp || !resp.success) {\n      el.innerHTML = '<div style=\"color:#b00;padding:10px;\">Overview Light AJAX failed<\/div>';\n      if (resp && resp.data && resp.data.message) {\n        el.innerHTML += '<div style=\"padding:10px;\">' + resp.data.message + '<\/div>';\n      }\n      return;\n    }\n    el.innerHTML = resp.data.html;\n  })\n  .catch(function(){\n    el.innerHTML = '<div style=\"color:#b00;padding:10px;\">Overview Light AJAX failed (network)<\/div>';\n  });\n});\n<\/script>\n  <\/div>\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>Campingplatz mit privaten Sanit\u00e4ranlagen in Drenthe Drenthe Campings, wo Sie Luxuscamping mit privaten Sanit\u00e4ranlagen genie\u00dfen k\u00f6nnen. Hier genie\u00dfen Sie das gewisse Extra an Komfort w\u00e4hrend eines wundersch\u00f6nen Campingurlaubs. Auf unseren Campingpl\u00e4tzen in Drenthe verf\u00fcgen Sie \u00fcber eigene Sanit\u00e4ranlagen auf Ihrem Stellplatz. Wie wunderbar ist es, im Toilettengeb\u00e4ude nicht anstehen zu m\u00fcssen? Keine Wege zum Toilettengeb\u00e4ude. [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":3317,"parent":5701,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"_acf_changed":false,"_tz_page_kind":"default","footnotes":""},"class_list":["post-5707","page","type-page","status-publish","has-post-thumbnail","hentry"],"acf":[],"_links":{"self":[{"href":"https:\/\/www.drenthecampings.nl\/de\/wp-json\/wp\/v2\/pages\/5707","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.drenthecampings.nl\/de\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/www.drenthecampings.nl\/de\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/www.drenthecampings.nl\/de\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.drenthecampings.nl\/de\/wp-json\/wp\/v2\/comments?post=5707"}],"version-history":[{"count":5,"href":"https:\/\/www.drenthecampings.nl\/de\/wp-json\/wp\/v2\/pages\/5707\/revisions"}],"predecessor-version":[{"id":7291,"href":"https:\/\/www.drenthecampings.nl\/de\/wp-json\/wp\/v2\/pages\/5707\/revisions\/7291"}],"up":[{"embeddable":true,"href":"https:\/\/www.drenthecampings.nl\/de\/wp-json\/wp\/v2\/pages\/5701"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.drenthecampings.nl\/de\/wp-json\/wp\/v2\/media\/3317"}],"wp:attachment":[{"href":"https:\/\/www.drenthecampings.nl\/de\/wp-json\/wp\/v2\/media?parent=5707"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}