(function () { if (window.__ptvPrydbuskeBedWidgetInit) return; window.__ptvPrydbuskeBedWidgetInit = true; var styleEl = document.createElement('style'); styleEl.textContent = "#ptv-prydbuske-bed-widget{--ptv-g:#1c4220;--ptv-gp:#f0f7f0;--ptv-gb:#c8e6ca;--ptv-tx:#1a1a1a;--ptv-gr:#6b7280;width:100%;max-width:100%;box-sizing:border-box;margin:1rem 0;border:1px solid var(--ptv-gb);border-radius:16px;background:#fafaf8;font-family:inherit;color:var(--ptv-tx);overflow:hidden}\n#ptv-prydbuske-bed-widget *{box-sizing:border-box}\n#ptv-prydbuske-bed-widget .ptv-bw-head{background:var(--ptv-g);color:#fff;padding:.9rem 1.2rem;font-weight:600;font-size:1.02rem;display:flex;align-items:center;justify-content:space-between;gap:.6rem;cursor:pointer;user-select:none}\n#ptv-prydbuske-bed-widget .ptv-bw-chevron{transition:transform .25s ease;font-size:.85rem;flex:none}\n#ptv-prydbuske-bed-widget.ptv-collapsed .ptv-bw-chevron{transform:rotate(-90deg)}\n#ptv-prydbuske-bed-widget .ptv-bw-body{transition:max-height .3s ease,padding .3s ease;max-height:6000px;overflow:hidden;padding:.8rem .7rem 1.3rem}\n#ptv-prydbuske-bed-widget.ptv-collapsed .ptv-bw-body{max-height:0;padding-top:0;padding-bottom:0}\n#ptv-prydbuske-bed-widget .ptv-bw-loading{padding:1.4rem;font-size:.9rem;color:var(--ptv-gr)}\n#ptv-prydbuske-bed-widget .ptv-bw-filters{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:.9rem 1.2rem;margin-bottom:1rem}\n#ptv-prydbuske-bed-widget .ptv-bw-filters .ptv-bw-field{min-width:0}\n@media (max-width:680px){#ptv-prydbuske-bed-widget .ptv-bw-filters{grid-template-columns:1fr}}\n#ptv-prydbuske-bed-widget .ptv-bw-field{margin-bottom:0}\n#ptv-prydbuske-bed-widget .ptv-bw-label{display:block;font-size:.8rem;font-weight:600;color:var(--ptv-g);margin-bottom:.4rem}\n#ptv-prydbuske-bed-widget .ptv-bw-pills{display:flex;flex-wrap:wrap;gap:.4rem}\n#ptv-prydbuske-bed-widget .ptv-bw-pill{border:1px solid var(--ptv-gb);background:#fff;border-radius:999px;padding:.35rem .8rem;font-size:.82rem;cursor:pointer;display:inline-flex;align-items:center;gap:.35rem;color:var(--ptv-tx)}\n#ptv-prydbuske-bed-widget .ptv-bw-pill:hover{border-color:var(--ptv-g)}\n#ptv-prydbuske-bed-widget .ptv-bw-pill.ptv-bw-active{background:var(--ptv-g);border-color:var(--ptv-g);color:#fff}\n#ptv-prydbuske-bed-widget .ptv-bw-swatch{width:12px;height:12px;border-radius:50%;border:1px solid var(--ptv-gb);flex:none}\n#ptv-prydbuske-bed-widget .ptv-bw-match-row{display:flex;align-items:center;justify-content:space-between;flex-wrap:wrap;gap:.5rem;margin:.2rem 0 .6rem}\n#ptv-prydbuske-bed-widget .ptv-bw-match-count{font-size:.8rem;color:var(--ptv-gr)}\n#ptv-prydbuske-bed-widget .ptv-bw-selected-count{font-size:.8rem;color:var(--ptv-g);font-weight:600}\n#ptv-prydbuske-bed-widget .ptv-bw-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(128px,1fr));gap:.6rem;max-height:620px;overflow-y:auto;padding:.6rem;border:1px solid var(--ptv-gb);border-radius:12px;background:#fff;margin-bottom:1rem}\n#ptv-prydbuske-bed-widget .ptv-bw-card{position:relative;border:1px solid var(--ptv-gb);border-radius:10px;padding:.45rem;cursor:pointer;background:#fff;transition:border-color .12s,background .12s}\n#ptv-prydbuske-bed-widget .ptv-bw-card:hover{border-color:var(--ptv-g)}\n#ptv-prydbuske-bed-widget .ptv-bw-card.ptv-bw-checked{border-color:var(--ptv-g);background:var(--ptv-gp)}\n#ptv-prydbuske-bed-widget .ptv-bw-card-img{width:100%;aspect-ratio:1;object-fit:cover;border-radius:7px;background:#eee;display:block}\n#ptv-prydbuske-bed-widget .ptv-bw-card-img.ptv-bw-noimg{display:flex;align-items:center;justify-content:center;font-size:1.6rem}\n#ptv-prydbuske-bed-widget .ptv-bw-card-navn{font-weight:600;font-size:.76rem;margin-top:.35rem;line-height:1.25}\n#ptv-prydbuske-bed-widget .ptv-bw-card-botanisk{font-style:italic;font-size:.66rem;color:var(--ptv-gr);line-height:1.2}\n#ptv-prydbuske-bed-widget .ptv-bw-card-check{position:absolute;top:.35rem;right:.35rem;width:22px;height:22px;border-radius:50%;background:rgba(255,255,255,.92);border:1.5px solid var(--ptv-gb);display:flex;align-items:center;justify-content:center;font-size:.78rem;font-weight:700;color:var(--ptv-g);box-shadow:0 1px 3px rgba(0,0,0,.2)}\n#ptv-prydbuske-bed-widget .ptv-bw-card.ptv-bw-checked .ptv-bw-card-check{background:var(--ptv-g);border-color:var(--ptv-g);color:#fff}\n#ptv-prydbuske-bed-widget .ptv-bw-grid-empty{padding:1.2rem;text-align:center;color:var(--ptv-gr);font-size:.85rem}\n#ptv-prydbuske-bed-widget .ptv-bw-areal-row{display:flex;flex-wrap:wrap;align-items:flex-end;gap:1.2rem;margin-bottom:.9rem}\n#ptv-prydbuske-bed-widget .ptv-bw-stepper{display:flex;align-items:center;gap:.5rem}\n#ptv-prydbuske-bed-widget .ptv-bw-stepper button{width:34px;height:34px;border-radius:8px;border:1px solid var(--ptv-gb);background:#fff;font-size:1.1rem;cursor:pointer;color:var(--ptv-g)}\n#ptv-prydbuske-bed-widget .ptv-bw-stepper button:hover{background:var(--ptv-gp)}\n#ptv-prydbuske-bed-widget .ptv-bw-stepper input{width:80px;text-align:center;padding:.4rem;border:1px solid var(--ptv-gb);border-radius:8px;font-size:.95rem}\n#ptv-prydbuske-bed-widget .ptv-bw-unit{font-size:.82rem;color:var(--ptv-gr)}\n#ptv-prydbuske-bed-widget .ptv-bw-actions{display:flex;flex-wrap:wrap;gap:.6rem;margin-bottom:1rem}\n#ptv-prydbuske-bed-widget .ptv-bw-btn-secondary{flex:1;min-width:170px;padding:.7rem 1rem;border-radius:10px;border:1.5px solid var(--ptv-g);background:#fff;color:var(--ptv-g);font-weight:600;font-size:.9rem;cursor:pointer}\n#ptv-prydbuske-bed-widget .ptv-bw-btn-secondary:hover{background:var(--ptv-gp)}\n#ptv-prydbuske-bed-widget .ptv-bw-btn-primary{flex:1;min-width:170px;padding:.7rem 1rem;border-radius:10px;border:none;background:var(--ptv-g);color:#fff;font-weight:600;font-size:.9rem;cursor:pointer}\n#ptv-prydbuske-bed-widget .ptv-bw-btn-primary:hover{background:#153318}\n#ptv-prydbuske-bed-widget .ptv-bw-btn-mini{padding:.65rem 1.1rem;border-radius:8px;border:none;background:var(--ptv-g);color:#fff;font-weight:600;font-size:.85rem;cursor:pointer;white-space:nowrap}\n#ptv-prydbuske-bed-widget .ptv-bw-btn-mini:hover{background:#153318}\n#ptv-prydbuske-bed-widget .ptv-bw-hint{font-size:.85rem;color:var(--ptv-gr);background:var(--ptv-gp);border-radius:10px;padding:.9rem 1rem;margin-bottom:1rem;text-align:center;line-height:1.4}\n#ptv-prydbuske-bed-widget .ptv-bw-empty{font-size:.85rem;color:#991b1b;background:#fef2f2;border-radius:10px;padding:.9rem 1rem;margin-bottom:1rem;text-align:center;line-height:1.4}\n#ptv-prydbuske-bed-widget .ptv-bw-tilvalg{margin-bottom:1rem;border:1px solid var(--ptv-gb);border-radius:12px;padding:.8rem 1rem;background:#fff}\n#ptv-prydbuske-bed-widget .ptv-bw-tilvalg-titel{font-size:.8rem;font-weight:600;color:var(--ptv-g);margin-bottom:.6rem}\n#ptv-prydbuske-bed-widget .ptv-bw-tilvalg-item{display:flex;align-items:center;gap:.6rem;padding:.4rem 0;border-bottom:1px solid var(--ptv-gb)}\n#ptv-prydbuske-bed-widget .ptv-bw-tilvalg-item:last-child{border-bottom:none}\n#ptv-prydbuske-bed-widget .ptv-bw-tilvalg-item input[type=checkbox]{width:18px;height:18px;flex:none;accent-color:var(--ptv-g)}\n#ptv-prydbuske-bed-widget .ptv-bw-tilvalg-img{width:40px;height:40px;border-radius:7px;object-fit:cover;flex:none;background:#eee}\n#ptv-prydbuske-bed-widget .ptv-bw-tilvalg-img.ptv-bw-noimg{display:flex;align-items:center;justify-content:center;font-size:1.1rem}\n#ptv-prydbuske-bed-widget .ptv-bw-tilvalg-tekst{min-width:0;flex:1}\n#ptv-prydbuske-bed-widget .ptv-bw-tilvalg-navn{font-weight:600;font-size:.82rem}\n#ptv-prydbuske-bed-widget .ptv-bw-tilvalg-pris{font-size:.75rem;color:var(--ptv-gr)}\n#ptv-prydbuske-bed-widget .ptv-bw-tilvalg-qty{width:56px;text-align:center;padding:.3rem;border:1px solid var(--ptv-gb);border-radius:7px;font-size:.85rem}\n#ptv-prydbuske-bed-widget .ptv-bw-resultat{margin-bottom:1rem}\n#ptv-prydbuske-bed-widget .ptv-bw-resultat-titel{font-size:.85rem;font-weight:600;color:var(--ptv-g);margin-bottom:.6rem}\n#ptv-prydbuske-bed-widget .ptv-bw-plantekort{display:flex;gap:.7rem;align-items:center;padding:.5rem 0;border-bottom:1px solid var(--ptv-gb)}\n#ptv-prydbuske-bed-widget .ptv-bw-plantekort:last-child{border-bottom:none}\n#ptv-prydbuske-bed-widget .ptv-bw-plantekort-img{width:52px;height:52px;border-radius:8px;object-fit:cover;flex:none;background:#eee}\n#ptv-prydbuske-bed-widget .ptv-bw-plantekort-img.ptv-bw-noimg{display:flex;align-items:center;justify-content:center;font-size:1.3rem}\n#ptv-prydbuske-bed-widget .ptv-bw-plantekort-tekst{min-width:0;flex:1}\n#ptv-prydbuske-bed-widget .ptv-bw-plantekort-navn{font-weight:600;font-size:.88rem}\n#ptv-prydbuske-bed-widget .ptv-bw-plantekort-botanisk{font-style:italic;font-size:.75rem;color:var(--ptv-gr)}\n#ptv-prydbuske-bed-widget .ptv-bw-plantekort-detaljer{font-size:.78rem;color:var(--ptv-gr);margin-top:.15rem}\n#ptv-prydbuske-bed-widget .ptv-bw-plantekort-pris{font-size:.85rem;font-weight:600;flex:none;text-align:right}\n#ptv-prydbuske-bed-widget .ptv-bw-pricebar{background:var(--ptv-g);color:#fff;border-radius:10px;padding:.8rem 1rem;margin-bottom:1rem;text-align:center}\n#ptv-prydbuske-bed-widget .ptv-bw-pricebar .ptv-bw-amount{font-size:1.4rem;font-weight:700}\n#ptv-prydbuske-bed-widget .ptv-bw-pricebar small{display:block;opacity:.85;font-size:.72rem;margin-top:2px}\n#ptv-prydbuske-bed-widget .ptv-bw-cta{width:100%;padding:.85rem;border:none;border-radius:10px;background:#2d5a27;color:#fff;font-size:1rem;font-weight:600;cursor:pointer}\n#ptv-prydbuske-bed-widget .ptv-bw-cta:hover{background:#234a1e}\n#ptv-prydbuske-bed-widget .ptv-bw-cta:disabled{opacity:.6;cursor:default}\n#ptv-prydbuske-bed-widget .ptv-bw-status{margin-top:.6rem;font-size:.82rem}\n#ptv-prydbuske-bed-widget .ptv-bw-status.ptv-error{color:#991b1b}\n#ptv-prydbuske-bed-widget .ptv-bw-status.ptv-ok{color:var(--ptv-g)}\n#ptv-prydbuske-bed-widget .ptv-bw-status a{color:var(--ptv-g);font-weight:600}\n#ptv-prydbuske-bed-widget .ptv-bw-disclaimer{font-size:.68rem;color:var(--ptv-gr);margin-top:.7rem;line-height:1.4}\n#ptv-prydbuske-bed-widget .ptv-bw-vaelg-alle{border:1px solid var(--ptv-gb);background:#fff;border-radius:999px;padding:.3rem .8rem;font-size:.78rem;cursor:pointer;color:var(--ptv-g);font-weight:600}\n#ptv-prydbuske-bed-widget .ptv-bw-vaelg-alle:hover{border-color:var(--ptv-g);background:var(--ptv-gp)}\n#ptv-prydbuske-bed-widget .ptv-bw-tv-total{margin-left:auto;font-weight:600;font-size:.85rem;color:var(--ptv-tx);flex:none}\n#ptv-prydbuske-bed-widget .ptv-bw-jordvalg-prompt{font-size:.85rem;background:#eff6ff;border:1px solid #bfdbfe;border-radius:10px;padding:.7rem .9rem;margin-bottom:.5rem}\n#ptv-prydbuske-bed-widget .ptv-bw-jordvalg-tekst{color:#1e40af;margin-bottom:.5rem;line-height:1.4}\n#ptv-prydbuske-bed-widget .ptv-bw-jordvalg-btns{display:flex;flex-wrap:wrap;gap:.5rem}\n#ptv-prydbuske-bed-widget .ptv-bw-tag{font-size:.68rem;background:var(--ptv-gb);color:var(--ptv-g);border-radius:10px;padding:1px 7px;margin-left:.4rem;font-weight:700}\n#ptv-prydbuske-bed-widget .ptv-bw-v-titel{font-size:1.15rem;font-weight:700;color:var(--ptv-g);margin:0 0 .9rem}\n#ptv-prydbuske-bed-widget .ptv-bw-vgrid{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:1rem;margin-bottom:1rem}\n@media (max-width:900px){#ptv-prydbuske-bed-widget .ptv-bw-vgrid{grid-template-columns:repeat(2,minmax(0,1fr))}}\n@media (max-width:560px){#ptv-prydbuske-bed-widget .ptv-bw-vgrid{grid-template-columns:1fr}}\n#ptv-prydbuske-bed-widget .ptv-bw-vcard{border:1px solid var(--ptv-gb);border-radius:12px;padding:.9rem;background:#fff;display:flex;flex-direction:column;gap:.3rem}\n#ptv-prydbuske-bed-widget .ptv-bw-vcard-img{width:100%;aspect-ratio:1;object-fit:cover;border-radius:9px;background:#eee;display:block}\n#ptv-prydbuske-bed-widget .ptv-bw-vcard-img.ptv-bw-noimg{display:flex;align-items:center;justify-content:center;font-size:2rem}\n#ptv-prydbuske-bed-widget .ptv-bw-vcard-navn{font-weight:700;font-size:1rem;margin-top:.3rem}\n#ptv-prydbuske-bed-widget .ptv-bw-vcard-botanisk{font-style:italic;font-size:.78rem;color:var(--ptv-gr)}\n#ptv-prydbuske-bed-widget .ptv-bw-vcard-pris{font-weight:600;font-size:1rem;color:var(--ptv-tx);margin-top:.1rem}\n#ptv-prydbuske-bed-widget .ptv-bw-vcard-row{display:flex;align-items:center;gap:.6rem;margin-top:auto;padding-top:.4rem}\n#ptv-prydbuske-bed-widget .ptv-bw-vcard-stepper{display:flex;align-items:center;gap:.35rem;flex:none}\n#ptv-prydbuske-bed-widget .ptv-bw-vcard-stepper button{width:28px;height:28px;border-radius:7px;border:1px solid var(--ptv-gb);background:#fff;font-size:.95rem;cursor:pointer;color:var(--ptv-g)}\n#ptv-prydbuske-bed-widget .ptv-bw-vcard-stepper button:hover{background:var(--ptv-gp)}\n#ptv-prydbuske-bed-widget .ptv-bw-vcard-qty{width:56px;text-align:center;padding:.25rem;border:1px solid var(--ptv-gb);border-radius:7px;font-size:.82rem;-moz-appearance:textfield}\n#ptv-prydbuske-bed-widget .ptv-bw-vcard-qty::-webkit-outer-spin-button,#ptv-prydbuske-bed-widget .ptv-bw-vcard-qty::-webkit-inner-spin-button{-webkit-appearance:none;margin:0}\n#ptv-prydbuske-bed-widget .ptv-bw-vcard-buy{flex:1;min-width:0;padding:.55rem .7rem;font-size:.82rem}\n#ptv-prydbuske-bed-widget .ptv-bw-field-full{grid-column:1/-1}\n#ptv-prydbuske-bed-widget .ptv-bw-subpills{margin-top:.5rem;padding-top:.5rem;border-top:1px dashed var(--ptv-gb)}\n#ptv-prydbuske-bed-widget .ptv-bw-vcard-storrelser{display:flex;flex-wrap:wrap;gap:.3rem;margin-top:.2rem}\n#ptv-prydbuske-bed-widget .ptv-bw-vcard-storrelse-pil{border:1px solid var(--ptv-gb);background:#fff;color:var(--ptv-tx);border-radius:999px;padding:.2rem .55rem;font-size:.72rem;cursor:pointer;line-height:1.3}\n#ptv-prydbuske-bed-widget .ptv-bw-vcard-storrelse-pil:hover{background:var(--ptv-gp)}\n#ptv-prydbuske-bed-widget .ptv-bw-vcard-storrelse-pil.ptv-bw-active{background:var(--ptv-g);border-color:var(--ptv-g);color:#fff}"; document.head.appendChild(styleEl); var MARKUP_VARIANT_HTML = "
🌳 Vælg dine favoritter – filtrér og læg direkte i kurven.
\n
Henter prydbuske…
\n"; var FARVE_PILLS = [ { vaerdi: 41, label: 'Hvid', hex: '#ffffff' }, { vaerdi: 42, label: 'Rosa', hex: '#f472b6' }, { vaerdi: 43, label: 'Rød', hex: '#dc2626' }, { vaerdi: 44, label: 'Gul', hex: '#facc15' }, { vaerdi: 46, label: 'Blå', hex: '#3b82f6' }, { vaerdi: 45, label: 'Lilla', hex: '#a855f7' }, { vaerdi: 50, label: 'Creme', hex: '#f5f0dc' }, { vaerdi: 48, label: 'Violet', hex: '#7c3aed' }, { vaerdi: 54, label: 'Grøn', hex: '#4ade80' }, { vaerdi: 47, label: 'Orange', hex: '#fb923c' }, { vaerdi: 49, label: 'Brun', hex: '#92400e' }, { vaerdi: 57, label: 'Bronze', hex: '#a97142' }, { vaerdi: 187, label: 'Grå', hex: '#9ca3af' } ]; var BLADFARVE_PILLS = [ { vaerdi: 34, label: 'Grøn', hex: '#4ade80' }, { vaerdi: 23, label: 'Rød', hex: '#dc2626' }, { vaerdi: 24, label: 'Gul', hex: '#facc15' }, { vaerdi: 185, label: 'Grå', hex: '#9ca3af' }, { vaerdi: 21, label: 'Hvid', hex: '#ffffff' }, { vaerdi: 11896, label: 'Mørkegrønne', hex: '#166534' }, { vaerdi: 183, label: 'Brogebladet', hex: null }, { vaerdi: 26, label: 'Blå', hex: '#3b82f6' }, { vaerdi: 14964, label: 'Purpurrøde', hex: '#7e22ce' }, { vaerdi: 37, label: 'Bronze', hex: '#a97142' }, { vaerdi: 12373, label: 'Grågrønne', hex: '#84a98c' }, { vaerdi: 16148, label: 'Blågrønne', hex: '#5f9ea0' }, { vaerdi: 18133, label: 'Gulgrønne', hex: '#a3c644' }, { vaerdi: 30, label: 'Creme', hex: '#f5f0dc' }, { vaerdi: 27, label: 'Orange', hex: '#fb923c' }, { vaerdi: 12640, label: 'Friskgrønne', hex: '#65d16f' }, { vaerdi: 17059, label: 'Hvidbrogede', hex: null }, { vaerdi: 18907, label: 'Gulbrogede', hex: null }, { vaerdi: 22, label: 'Rosa', hex: '#f472b6' } ]; var VAEKSTFORM_PILLS = [ { vaerdi: 356, label: 'Rund krone' }, { vaerdi: 3552, label: 'Vaseform' }, { vaerdi: 358, label: 'Kugleformet' }, { vaerdi: 3553, label: 'Oval' }, { vaerdi: 355, label: 'Bunddækkende' }, { vaerdi: 353, label: 'Pyramideformet' }, { vaerdi: 359, label: 'Bredkronet' }, { vaerdi: 354, label: 'Kegleformet' }, { vaerdi: 3551, label: 'Hængende krone' }, { vaerdi: 357, label: 'Søjleformet' }, { vaerdi: 360, label: 'Slyngende' }, { vaerdi: 3550, label: 'Parasolform' } ]; var EFTERAARSLOEV_PILLS = [ { vaerdi: 64, label: 'Gul', hex: '#facc15' }, { vaerdi: 63, label: 'Rød', hex: '#dc2626' }, { vaerdi: 77, label: 'Bronze', hex: '#a97142' }, { vaerdi: 67, label: 'Orange', hex: '#fb923c' }, { vaerdi: 69, label: 'Brun', hex: '#92400e' }, { vaerdi: 192, label: 'Kobber', hex: '#b87333' } ]; var LYS_PILLS = [ { key: 'fuld_sol', label: 'Fuld sol' }, { key: 'halvskygge', label: 'Halvskygge' }, { key: 'skygge', label: 'Skygge' } ]; var LYS_MATCH = { fuld_sol: [2, 4, 3], halvskygge: [5, 4, 7], skygge: [6, 3, 7] }; var JORD_PILLS = [ { key: 'toer', label: 'Tør' }, { key: 'fugtig', label: 'Fugtig' }, { key: 'almindelig', label: 'Almindelig' } ]; var JORD_BUCKET = { 1: 'almindelig', 2: 'fugtig', 3: 'toer', 4: 'toer', 5: 'toer', 6: 'fugtig', 7: 'almindelig', 8: 'almindelig', 9: 'almindelig', 10: 'almindelig', 11: 'almindelig', 12: 'almindelig', 13: 'fugtig', 14: 'almindelig', 15: 'almindelig', 16: 'fugtig', 17: 'almindelig', 18: 'almindelig', 19: 'toer', 20: 'almindelig' }; var JORD_TIL_TYPE = { toer: 'let_jord', almindelig: 'alm_havemuld', fugtig: 'fed_jord' }; var HOEJDE_PILLS = [ { vaerdi: 52002, label: '0-25 cm' }, { vaerdi: 52003, label: '25-50 cm' }, { vaerdi: 52004, label: '50-100 cm' }, { vaerdi: 52005, label: '1-2 m' }, { vaerdi: 52006, label: '2-5 m' }, { vaerdi: 52007, label: '5-10 m' } ]; var SAESON_PILLS = [ { key: 'foraar', label: 'Forår' }, { key: 'sommer', label: 'Sommer' }, { key: 'efteraar', label: 'Efterår' }, { key: 'vinter', label: 'Vinter' } ]; var SAESON_MATCH = { foraar: [2, 3, 9], sommer: [3, 4, 5], efteraar: [5, 6, 7], vinter: [7, 8, 9] }; var ANVENDELSE_PILLS = [ { vaerdi: 348, label: 'Hække' }, { vaerdi: 51766, label: 'Solitær' }, { vaerdi: 334, label: 'Parker' }, { vaerdi: 349, label: 'Krukker' }, { vaerdi: 51764, label: 'Staudebed' }, { vaerdi: 335, label: 'Terasse' }, { vaerdi: 352, label: 'Skråninger' }, { vaerdi: 361, label: 'Læhegn' }, { vaerdi: 51781, label: 'Gruppeplantning' }, { vaerdi: 51790, label: 'Hegn' }, { vaerdi: 51767, label: 'Kantplanter' }, { vaerdi: 351, label: 'Mure' }, { vaerdi: 51780, label: 'Fritvoksende hæk' }, { vaerdi: 51765, label: 'Bunddække' }, { vaerdi: 51769, label: 'Naturhave' }, { vaerdi: 51778, label: 'Busket' }, { vaerdi: 51770, label: 'Snitblomst' }, { vaerdi: 51793, label: 'Indkørsel' }, { vaerdi: 363, label: 'Køkkenhaver' }, { vaerdi: 51779, label: 'Blomstrende hæk' }, { vaerdi: 362, label: 'Espalier' }, { vaerdi: 51774, label: 'Formklip' }, { vaerdi: 51792, label: 'Altan' }, { vaerdi: 51777, label: 'Kystnær' }, { vaerdi: 51776, label: 'Skovbed' }, { vaerdi: 51775, label: 'Stenhøj' }, { vaerdi: 51773, label: 'Altankasse' }, { vaerdi: 51795, label: 'Indgangsparti' }, { vaerdi: 51788, label: 'Skyggebed' } ]; var OVRIGE_PILLS = [ { vaerdi: 51991, label: 'Insektvenlig' }, { vaerdi: 51988, label: 'Bivenlig' }, { vaerdi: 51990, label: 'Fuglevenlig' }, { vaerdi: 51989, label: 'Duftende' }, { vaerdi: 51997, label: 'Lang blomstring' }, { vaerdi: 52000, label: 'Vinterblomstring' }, { vaerdi: 51993, label: 'Salttolerant' }, { vaerdi: 51994, label: 'Vindtolerant' } ]; var TILVALG_LABELS = { plantejord: '🌱', godning: '🌾', felco: '✂️', ukrudtsdug: '🟤' }; function applyFieldWidth(fieldEl, vis) { if (!fieldEl) return; fieldEl.classList.toggle('ptv-bw-field-full', vis.length > 6); } function initVariantWidget(ROOT, UNDERKAT_ID, DATA_URL, KURV_URL) { ROOT.innerHTML = MARKUP_VARIANT_HTML; var el = { head: ROOT.querySelector('#ptv-bw-head'), loading: ROOT.querySelector('#ptv-bw-loading'), body: ROOT.querySelector('#ptv-bw-body'), titel: ROOT.querySelector('#ptv-bw-v-titel'), farveField: ROOT.querySelector('#ptv-bw-v-farve-field'), farvePills: ROOT.querySelector('#ptv-bw-v-farve-pills'), hoejdeField: ROOT.querySelector('#ptv-bw-v-hoejde-field'), hoejdePills: ROOT.querySelector('#ptv-bw-v-hoejde-pills'), saesonField: ROOT.querySelector('#ptv-bw-v-saeson-field'), saesonPills: ROOT.querySelector('#ptv-bw-v-saeson-pills'), anvendelseField: ROOT.querySelector('#ptv-bw-v-anvendelse-field'), anvendelsePills: ROOT.querySelector('#ptv-bw-v-anvendelse-pills'), ovrigeField: ROOT.querySelector('#ptv-bw-v-ovrige-field'), ovrigePills: ROOT.querySelector('#ptv-bw-v-ovrige-pills'), vaekstformField: ROOT.querySelector('#ptv-bw-v-vaekstform-field'), vaekstformPills: ROOT.querySelector('#ptv-bw-v-vaekstform-pills'), bladfarveField: ROOT.querySelector('#ptv-bw-v-bladfarve-field'), bladfarvePills: ROOT.querySelector('#ptv-bw-v-bladfarve-pills'), efteraarsloevField: ROOT.querySelector('#ptv-bw-v-efteraarsloev-field'), efteraarsloevPills: ROOT.querySelector('#ptv-bw-v-efteraarsloev-pills'), matchCount: ROOT.querySelector('#ptv-bw-v-match-count'), grid: ROOT.querySelector('#ptv-bw-v-grid'), empty: ROOT.querySelector('#ptv-bw-v-empty'), status: ROOT.querySelector('#ptv-bw-v-status') }; var DATA = null; var valgtFarver = []; var valgtHoejde = []; var valgtSaeson = []; var valgtAnvendelse = []; var valgtOvrige = []; var valgtVaekstform = []; var valgtBladfarve = []; var valgtEfteraarsloev = []; var qtyState = {}; var variantValgt = {}; var FARVE_VIS = [], HOEJDE_VIS = [], SAESON_VIS = [], ANVENDELSE_VIS = [], OVRIGE_VIS = [], VAEKSTFORM_VIS = [], BLADFARVE_VIS = [], EFTERAARSLOEV_VIS = []; function fmtKr(n) { var v = Math.round((n + 1e-9) * 100) / 100; var parts = v.toFixed(2).split('.'); var intPart = parts[0]; var decPart = parts[1]; var out = ''; for (var i = 0; i < intPart.length; i++) { if (i > 0 && (intPart.length - i) % 3 === 0) out += '.'; out += intPart[i]; } return out + ',' + decPart; } function findPris(trin, qty) { if (!trin || trin.length === 0) return null; var vaerdi = trin[0][1]; for (var i = 0; i < trin.length; i++) { if (trin[i][0] <= qty) vaerdi = trin[i][1]; } return vaerdi; } function effectiveVarenrTrin(p) { if (p.varianter && p.varianter.length) { var idx = getVariantIndex(p); var v = p.varianter[idx] || p.varianter[p.variant_default_index] || p.varianter[0]; return { varenr: v.varenr, trin: v.trin }; } return { varenr: p.varenr, trin: p.trin }; } function effectiveFrekvens(p) { if (p.varianter && p.varianter.length) { var idx = getVariantIndex(p); var v = p.varianter[idx] || p.varianter[p.variant_default_index] || p.varianter[0]; return v.frekvens > 0 ? v.frekvens : 1; } return p.frekvens > 0 ? p.frekvens : 1; } function snapTilFrekvens(qty, frekvens) { var f = frekvens > 0 ? frekvens : 1; var rundet = Math.round(qty / f) * f; return Math.max(f, rundet); } function unionMatchSet(map, keys) { var out = []; keys.forEach(function (k) { var set = map[k] || []; set.forEach(function (id) { if (out.indexOf(id) === -1) out.push(id); }); }); return out; } function matchFilter(p) { if (valgtFarver.length) { if (!p.farve_ids.some(function (id) { return valgtFarver.indexOf(id) !== -1; })) return false; } if (valgtHoejde.length) { if (!p.hoejde_ids.some(function (id) { return valgtHoejde.indexOf(id) !== -1; })) return false; } if (valgtSaeson.length) { var saesonSet = unionMatchSet(SAESON_MATCH, valgtSaeson); if (saesonSet.indexOf(p.blomstring_id) === -1) return false; } if (valgtAnvendelse.length) { if (!p.anvendelse_ids.some(function (id) { return valgtAnvendelse.indexOf(id) !== -1; })) return false; } if (valgtOvrige.length) { if (!p.ovrige_ids.some(function (id) { return valgtOvrige.indexOf(id) !== -1; })) return false; } if (valgtVaekstform.length) { if (!p.vaekstform_ids.some(function (id) { return valgtVaekstform.indexOf(id) !== -1; })) return false; } if (valgtBladfarve.length) { if (!p.bladfarve_ids.some(function (id) { return valgtBladfarve.indexOf(id) !== -1; })) return false; } if (valgtEfteraarsloev.length) { if (!p.efteraarsloev_ids.some(function (id) { return valgtEfteraarsloev.indexOf(id) !== -1; })) return false; } return true; } function computeUsedFilterSets(kandidater) { var farve = [], hoejde = [], saeson = [], anvendelse = [], ovrige = [], vaekstform = [], bladfarve = [], efteraarsloev = []; kandidater.forEach(function (p) { p.farve_ids.forEach(function (id) { if (farve.indexOf(id) === -1) farve.push(id); }); p.hoejde_ids.forEach(function (id) { if (hoejde.indexOf(id) === -1) hoejde.push(id); }); p.anvendelse_ids.forEach(function (id) { if (anvendelse.indexOf(id) === -1) anvendelse.push(id); }); p.ovrige_ids.forEach(function (id) { if (ovrige.indexOf(id) === -1) ovrige.push(id); }); p.vaekstform_ids.forEach(function (id) { if (vaekstform.indexOf(id) === -1) vaekstform.push(id); }); p.bladfarve_ids.forEach(function (id) { if (bladfarve.indexOf(id) === -1) bladfarve.push(id); }); p.efteraarsloev_ids.forEach(function (id) { if (efteraarsloev.indexOf(id) === -1) efteraarsloev.push(id); }); SAESON_PILLS.forEach(function (pill) { if (saeson.indexOf(pill.key) !== -1) return; var set = SAESON_MATCH[pill.key] || []; if (set.indexOf(p.blomstring_id) !== -1) saeson.push(pill.key); }); }); return { farve: FARVE_PILLS.filter(function (p) { return farve.indexOf(p.vaerdi) !== -1; }), hoejde: HOEJDE_PILLS.filter(function (p) { return hoejde.indexOf(p.vaerdi) !== -1; }), saeson: SAESON_PILLS.filter(function (p) { return saeson.indexOf(p.key) !== -1; }), anvendelse: ANVENDELSE_PILLS.filter(function (p) { return anvendelse.indexOf(p.vaerdi) !== -1; }), ovrige: OVRIGE_PILLS.filter(function (p) { return ovrige.indexOf(p.vaerdi) !== -1; }), vaekstform: VAEKSTFORM_PILLS.filter(function (p) { return vaekstform.indexOf(p.vaerdi) !== -1; }), bladfarve: BLADFARVE_PILLS.filter(function (p) { return bladfarve.indexOf(p.vaerdi) !== -1; }), efteraarsloev: EFTERAARSLOEV_PILLS.filter(function (p) { return efteraarsloev.indexOf(p.vaerdi) !== -1; }) }; } function renderFlervalgPills(container, pills, valgteListe, getKey, onToggle) { container.innerHTML = pills.map(function (p) { var vaerdi = getKey(p); var aktiv = valgteListe.indexOf(vaerdi) !== -1; var swatch = p.hex ? '' : ''; return ''; }).join(''); Array.prototype.forEach.call(container.querySelectorAll('.ptv-bw-pill'), function (btn) { btn.addEventListener('click', function () { var raw = btn.getAttribute('data-v'); var v = isNaN(Number(raw)) ? raw : Number(raw); onToggle(v); }); }); } function toggleFarve(v) { var idx = valgtFarver.indexOf(v); if (idx === -1) valgtFarver.push(v); else valgtFarver.splice(idx, 1); renderFarvePills(); render(); } function renderFarvePills() { renderFlervalgPills(el.farvePills, FARVE_VIS, valgtFarver, function (p) { return p.vaerdi; }, toggleFarve); } function toggleHoejde(v) { var idx = valgtHoejde.indexOf(v); if (idx === -1) valgtHoejde.push(v); else valgtHoejde.splice(idx, 1); renderHoejdePills(); render(); } function renderHoejdePills() { renderFlervalgPills(el.hoejdePills, HOEJDE_VIS, valgtHoejde, function (p) { return p.vaerdi; }, toggleHoejde); } function toggleAnvendelse(v) { var idx = valgtAnvendelse.indexOf(v); if (idx === -1) valgtAnvendelse.push(v); else valgtAnvendelse.splice(idx, 1); renderAnvendelsePills(); render(); } function renderAnvendelsePills() { renderFlervalgPills(el.anvendelsePills, ANVENDELSE_VIS, valgtAnvendelse, function (p) { return p.vaerdi; }, toggleAnvendelse); } function toggleOvrige(v) { var idx = valgtOvrige.indexOf(v); if (idx === -1) valgtOvrige.push(v); else valgtOvrige.splice(idx, 1); renderOvrigePills(); render(); } function renderOvrigePills() { renderFlervalgPills(el.ovrigePills, OVRIGE_VIS, valgtOvrige, function (p) { return p.vaerdi; }, toggleOvrige); } function toggleVaekstform(v) { var idx = valgtVaekstform.indexOf(v); if (idx === -1) valgtVaekstform.push(v); else valgtVaekstform.splice(idx, 1); renderVaekstformPills(); render(); } function renderVaekstformPills() { renderFlervalgPills(el.vaekstformPills, VAEKSTFORM_VIS, valgtVaekstform, function (p) { return p.vaerdi; }, toggleVaekstform); } function toggleBladfarve(v) { var idx = valgtBladfarve.indexOf(v); if (idx === -1) valgtBladfarve.push(v); else valgtBladfarve.splice(idx, 1); renderBladfarvePills(); render(); } function renderBladfarvePills() { renderFlervalgPills(el.bladfarvePills, BLADFARVE_VIS, valgtBladfarve, function (p) { return p.vaerdi; }, toggleBladfarve); } function toggleEfteraarsloev(v) { var idx = valgtEfteraarsloev.indexOf(v); if (idx === -1) valgtEfteraarsloev.push(v); else valgtEfteraarsloev.splice(idx, 1); renderEfteraarsloevPills(); render(); } function renderEfteraarsloevPills() { renderFlervalgPills(el.efteraarsloevPills, EFTERAARSLOEV_VIS, valgtEfteraarsloev, function (p) { return p.vaerdi; }, toggleEfteraarsloev); } function toggleSaeson(v) { var idx = valgtSaeson.indexOf(v); if (idx === -1) valgtSaeson.push(v); else valgtSaeson.splice(idx, 1); renderSaesonPills(); render(); } function renderSaesonPills() { renderFlervalgPills(el.saesonPills, SAESON_VIS, valgtSaeson, function (p) { return p.key; }, toggleSaeson); } function renderFilterFields() { el.farveField.hidden = FARVE_VIS.length === 0; el.hoejdeField.hidden = HOEJDE_VIS.length === 0; el.saesonField.hidden = SAESON_VIS.length === 0; el.anvendelseField.hidden = ANVENDELSE_VIS.length === 0; el.ovrigeField.hidden = OVRIGE_VIS.length === 0; el.vaekstformField.hidden = VAEKSTFORM_VIS.length === 0; el.bladfarveField.hidden = BLADFARVE_VIS.length === 0; el.efteraarsloevField.hidden = EFTERAARSLOEV_VIS.length === 0; applyFieldWidth(el.farveField, FARVE_VIS); applyFieldWidth(el.hoejdeField, HOEJDE_VIS); applyFieldWidth(el.saesonField, SAESON_VIS); applyFieldWidth(el.anvendelseField, ANVENDELSE_VIS); applyFieldWidth(el.ovrigeField, OVRIGE_VIS); applyFieldWidth(el.vaekstformField, VAEKSTFORM_VIS); applyFieldWidth(el.bladfarveField, BLADFARVE_VIS); applyFieldWidth(el.efteraarsloevField, EFTERAARSLOEV_VIS); renderFarvePills(); renderHoejdePills(); renderSaesonPills(); renderAnvendelsePills(); renderOvrigePills(); renderVaekstformPills(); renderBladfarvePills(); renderEfteraarsloevPills(); } function getQty(p) { var frekvens = effectiveFrekvens(p); var gemt = qtyState[p.plante_id]; if (gemt == null) return frekvens; return snapTilFrekvens(gemt, frekvens); } function getVariantIndex(p) { if (!p.varianter || !p.varianter.length) return 0; var idx = variantValgt[p.plante_id]; return idx == null ? p.variant_default_index : idx; } function storrelsePillsHtml(p) { // Vis også en enkelt størrelses-pille når planten kun har én gyldig variant - kunden // kan så stadig se hvilken størrelse/leveringsform prisen gælder for (Bjarnes regel: // "når der kun er en variant må de stadig godt vises"). if (!p.varianter || p.varianter.length < 1) return ''; var idx = getVariantIndex(p); return '
' + p.varianter.map(function (v, i) { return ''; }).join('') + '
'; } function cardPrisHtml(p) { var qty = getQty(p); var eff = effectiveVarenrTrin(p); var enhedsPris = findPris(eff.trin, qty) || 0; return fmtKr(enhedsPris * DATA.moms_faktor) + ' kr/stk'; } function laegIKurv(btn, p) { var qty = getQty(p); var eff = effectiveVarenrTrin(p); btn.disabled = true; el.status.className = 'ptv-bw-status'; el.status.textContent = 'Opretter kurv…'; fetch(KURV_URL, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ items: [{ vareNr: eff.varenr, quantity: qty }] }) }) .then(function (r) { return r.json(); }) .then(function (res) { btn.disabled = false; if (res && res.success && res.url) { el.status.className = 'ptv-bw-status ptv-ok'; el.status.innerHTML = 'Kurv oprettet — sender dig til kurven…'; try { var topWin = window.top || window.parent || window; topWin.location.href = res.url; } catch (e) { el.status.innerHTML = 'Kurv oprettet — gå til kurv →'; } } else { el.status.className = 'ptv-bw-status ptv-error'; el.status.textContent = 'Kunne ikke oprette kurven automatisk. Prøv igen om lidt.'; } }) .catch(function () { btn.disabled = false; el.status.className = 'ptv-bw-status ptv-error'; el.status.textContent = 'Kunne ikke oprette kurven automatisk. Prøv igen om lidt.'; }); } function opdaterKortStorrelse(id, idx) { var p = DATA.kandidater.filter(function (x) { return x.plante_id === id; })[0]; if (!p || !p.varianter || !p.varianter[idx]) return; variantValgt[id] = idx; // Forskellige varianter kan have forskellig Frekvens (fx potte=1, barrods=10) - // genberegn og fastlås antallet til den nye variants frekvens-krav. qtyState[id] = getQty(p); opdaterKortPris(id); var kort = el.grid.querySelector('[data-id="' + id + '"]'); if (!kort) return; Array.prototype.forEach.call(kort.querySelectorAll('.ptv-bw-vcard-storrelse-pil'), function (btn) { btn.classList.toggle('ptv-bw-active', parseInt(btn.getAttribute('data-idx'), 10) === idx); }); } function opdaterKortPrisTekst(id) { var kort = el.grid.querySelector('[data-id="' + id + '"]'); if (!kort) return; var prisEl = kort.querySelector('.ptv-bw-vcard-pris'); var p = DATA.kandidater.filter(function (x) { return x.plante_id === id; })[0]; if (!p) return; if (prisEl) prisEl.textContent = cardPrisHtml(p); } function opdaterKortPris(id) { var kort = el.grid.querySelector('[data-id="' + id + '"]'); if (!kort) return; var p = DATA.kandidater.filter(function (x) { return x.plante_id === id; })[0]; if (!p) return; var prisEl = kort.querySelector('.ptv-bw-vcard-pris'); var qtyInput = kort.querySelector('.ptv-bw-vcard-qty'); if (prisEl) prisEl.textContent = cardPrisHtml(p); if (qtyInput) { var frekvens = effectiveFrekvens(p); qtyInput.value = getQty(p); qtyInput.min = frekvens; qtyInput.step = frekvens; } } function renderGrid(pool) { if (pool.length === 0) { el.grid.innerHTML = ''; el.empty.hidden = false; return; } el.empty.hidden = true; el.grid.innerHTML = pool.map(function (p) { var imgHtml = p.billede ? '' : '
🌱
'; return '
' + imgHtml + '
' + p.navn + '
' + '
' + p.navn_botanisk + '
' + '
' + cardPrisHtml(p) + '
' + storrelsePillsHtml(p) + '
' + '
' + '' + '' + '' + '
' + '' + '
' + '
'; }).join(''); Array.prototype.forEach.call(el.grid.querySelectorAll('.ptv-bw-vcard'), function (kort) { var id = parseInt(kort.getAttribute('data-id'), 10); var p = pool.filter(function (x) { return x.plante_id === id; })[0]; var qtyInput = kort.querySelector('.ptv-bw-vcard-qty'); kort.querySelector('.ptv-bw-vcard-minus').addEventListener('click', function () { var frekvens = effectiveFrekvens(p); qtyState[id] = Math.max(frekvens, getQty(p) - frekvens); opdaterKortPris(id); }); kort.querySelector('.ptv-bw-vcard-plus').addEventListener('click', function () { var frekvens = effectiveFrekvens(p); qtyState[id] = getQty(p) + frekvens; opdaterKortPris(id); }); qtyInput.addEventListener('input', function () { // Løbende feedback mens der tastes, uden at overskrive feltet med den // frekvens-rettede værdi (det ville gøre det umuligt at taste et flercifret // antal). Selve rettelsen/afrundingen til nærmeste gyldige Frekvens-multiplum // sker først ved 'change' (blur/enter), se nedenfor. qtyState[id] = Math.max(1, parseInt(qtyInput.value, 10) || 1); opdaterKortPrisTekst(id); }); qtyInput.addEventListener('change', function () { qtyState[id] = getQty(p); opdaterKortPris(id); }); Array.prototype.forEach.call(kort.querySelectorAll('.ptv-bw-vcard-storrelse-pil'), function (pil) { pil.addEventListener('click', function () { opdaterKortStorrelse(id, parseInt(pil.getAttribute('data-idx'), 10)); }); }); kort.querySelector('.ptv-bw-vcard-buy').addEventListener('click', function (ev) { laegIKurv(ev.currentTarget, p); }); }); } function render() { if (!DATA) return; var pool = DATA.kandidater.filter(matchFilter); el.matchCount.textContent = pool.length + ' prydbuske matcher dine filtre'; renderGrid(pool); } function fetchData() { fetch(DATA_URL).then(function (r) { return r.json(); }).then(function (json) { if (!json || !json.ok) { el.loading.textContent = 'Kunne ikke hente prydbuske lige nu. Prøv at genindlæse siden.'; return; } DATA = json; el.loading.hidden = true; el.body.hidden = false; el.titel.textContent = 'Vælg dine favorit ' + (DATA.underkategori_navn || 'prydbuske'); var vis = computeUsedFilterSets(DATA.kandidater); FARVE_VIS = vis.farve; HOEJDE_VIS = vis.hoejde; SAESON_VIS = vis.saeson; ANVENDELSE_VIS = vis.anvendelse; OVRIGE_VIS = vis.ovrige; VAEKSTFORM_VIS = vis.vaekstform; BLADFARVE_VIS = vis.bladfarve; EFTERAARSLOEV_VIS = vis.efteraarsloev; renderFilterFields(); render(); }).catch(function () { el.loading.textContent = 'Kunne ikke hente prydbuske lige nu. Prøv at genindlæse siden.'; }); } el.head.addEventListener('click', function () { ROOT.classList.toggle('ptv-collapsed'); }); fetchData(); } var ROOTS = document.querySelectorAll('#ptv-prydbuske-bed-widget'); Array.prototype.forEach.call(ROOTS, function (ROOT) { if (ROOT.__ptvInit) return; ROOT.__ptvInit = true; var UNDERKAT_ID = ROOT.getAttribute('data-underkategori-id') || ''; var DATA_URL = 'https://n8n.plantetorvet.dk/webhook/prydbuske-bed-widget-data' + (UNDERKAT_ID ? '?underkategori_id=' + encodeURIComponent(UNDERKAT_ID) : ''); var KURV_URL = 'https://n8n.plantetorvet.dk/webhook/prydbuske-bed-widget-kurv'; if (UNDERKAT_ID) { initVariantWidget(ROOT, UNDERKAT_ID, DATA_URL, KURV_URL); return; } ROOT.innerHTML = "
🌳 Byg dit bed – filtrér, marker de prydbuske du vil have, og beregn mængde og pris.
\n
Henter prydbuske…
\n"; var el = { head: ROOT.querySelector('#ptv-bw-head'), loading: ROOT.querySelector('#ptv-bw-loading'), body: ROOT.querySelector('#ptv-bw-body'), farveField: ROOT.querySelector('#ptv-bw-farve-field'), farvePills: ROOT.querySelector('#ptv-bw-farve-pills'), lysField: ROOT.querySelector('#ptv-bw-lys-field'), lysPills: ROOT.querySelector('#ptv-bw-lys-pills'), jordField: ROOT.querySelector('#ptv-bw-jord-field'), jordPills: ROOT.querySelector('#ptv-bw-jord-pills'), hoejdeField: ROOT.querySelector('#ptv-bw-hoejde-field'), hoejdePills: ROOT.querySelector('#ptv-bw-hoejde-pills'), saesonField: ROOT.querySelector('#ptv-bw-saeson-field'), saesonPills: ROOT.querySelector('#ptv-bw-saeson-pills'), anvendelseField: ROOT.querySelector('#ptv-bw-anvendelse-field'), anvendelsePills: ROOT.querySelector('#ptv-bw-anvendelse-pills'), ovrigeField: ROOT.querySelector('#ptv-bw-ovrige-field'), ovrigePills: ROOT.querySelector('#ptv-bw-ovrige-pills'), vaekstformField: ROOT.querySelector('#ptv-bw-vaekstform-field'), vaekstformPills: ROOT.querySelector('#ptv-bw-vaekstform-pills'), bladfarveField: ROOT.querySelector('#ptv-bw-bladfarve-field'), bladfarvePills: ROOT.querySelector('#ptv-bw-bladfarve-pills'), efteraarsloevField: ROOT.querySelector('#ptv-bw-efteraarsloev-field'), efteraarsloevPills: ROOT.querySelector('#ptv-bw-efteraarsloev-pills'), matchCount: ROOT.querySelector('#ptv-bw-match-count'), vaelgAlleBtn: ROOT.querySelector('#ptv-bw-vaelg-alle'), selectedCount: ROOT.querySelector('#ptv-bw-selected-count'), grid: ROOT.querySelector('#ptv-bw-grid'), areal: ROOT.querySelector('#ptv-bw-areal'), arealMinus: ROOT.querySelector('#ptv-bw-areal-minus'), arealPlus: ROOT.querySelector('#ptv-bw-areal-plus'), beregnBtn: ROOT.querySelector('#ptv-bw-beregn'), beregnBtnTop: ROOT.querySelector('#ptv-bw-beregn-top'), hint: ROOT.querySelector('#ptv-bw-hint'), empty: ROOT.querySelector('#ptv-bw-empty'), tilvalgSection: ROOT.querySelector('#ptv-bw-tilvalg-section'), tilvalgListe: ROOT.querySelector('#ptv-bw-tilvalg-liste'), resultat: ROOT.querySelector('#ptv-bw-resultat'), resultatTitel: ROOT.querySelector('#ptv-bw-resultat-titel'), resultatListe: ROOT.querySelector('#ptv-bw-resultat-liste'), pricebar: ROOT.querySelector('#ptv-bw-pricebar'), cta: ROOT.querySelector('#ptv-bw-cta'), status: ROOT.querySelector('#ptv-bw-status'), disclaimer: ROOT.querySelector('#ptv-bw-disclaimer') }; var DATA = null; var valgtFarver = []; var valgtLys = []; var valgtJord = null; var jordvalgFed = null; var valgtHoejde = []; var valgtSaeson = []; var valgtAnvendelse = []; var valgtOvrige = []; var valgtVaekstform = []; var valgtBladfarve = []; var valgtEfteraarsloev = []; var valgteProdukter = {}; var valgteTilvalg = {}; var sidsteValgt = []; var FARVE_VIS = [], LYS_VIS = [], JORD_VIS = [], HOEJDE_VIS = [], SAESON_VIS = [], ANVENDELSE_VIS = [], OVRIGE_VIS = [], VAEKSTFORM_VIS = [], BLADFARVE_VIS = [], EFTERAARSLOEV_VIS = []; function fmtKr(n) { var v = Math.round((n + 1e-9) * 100) / 100; var parts = v.toFixed(2).split('.'); var intPart = parts[0]; var decPart = parts[1]; var out = ''; for (var i = 0; i < intPart.length; i++) { if (i > 0 && (intPart.length - i) % 3 === 0) out += '.'; out += intPart[i]; } return out + ',' + decPart; } function findPris(trin, qty) { if (!trin || trin.length === 0) return null; var vaerdi = trin[0][1]; for (var i = 0; i < trin.length; i++) { if (trin[i][0] <= qty) vaerdi = trin[i][1]; } return vaerdi; } function getAreal() { return Math.max(0, parseFloat(el.areal.value) || 0); } function renderFlervalgPills(container, pills, valgteListe, getKey, onToggle) { container.innerHTML = pills.map(function (p) { var vaerdi = getKey(p); var aktiv = valgteListe.indexOf(vaerdi) !== -1; var swatch = p.hex ? '' : ''; return ''; }).join(''); Array.prototype.forEach.call(container.querySelectorAll('.ptv-bw-pill'), function (btn) { btn.addEventListener('click', function () { var raw = btn.getAttribute('data-v'); var v = isNaN(Number(raw)) ? raw : Number(raw); onToggle(v); }); }); } function toggleFarve(v) { var idx = valgtFarver.indexOf(v); if (idx === -1) valgtFarver.push(v); else valgtFarver.splice(idx, 1); renderFarvePills(); render(); } function renderFarvePills() { renderFlervalgPills(el.farvePills, FARVE_VIS, valgtFarver, function (p) { return p.vaerdi; }, toggleFarve); } function toggleHoejde(v) { var idx = valgtHoejde.indexOf(v); if (idx === -1) valgtHoejde.push(v); else valgtHoejde.splice(idx, 1); renderHoejdePills(); render(); } function renderHoejdePills() { renderFlervalgPills(el.hoejdePills, HOEJDE_VIS, valgtHoejde, function (p) { return p.vaerdi; }, toggleHoejde); } function toggleAnvendelse(v) { var idx = valgtAnvendelse.indexOf(v); if (idx === -1) valgtAnvendelse.push(v); else valgtAnvendelse.splice(idx, 1); renderAnvendelsePills(); render(); } function renderAnvendelsePills() { renderFlervalgPills(el.anvendelsePills, ANVENDELSE_VIS, valgtAnvendelse, function (p) { return p.vaerdi; }, toggleAnvendelse); } function toggleOvrige(v) { var idx = valgtOvrige.indexOf(v); if (idx === -1) valgtOvrige.push(v); else valgtOvrige.splice(idx, 1); renderOvrigePills(); render(); } function renderOvrigePills() { renderFlervalgPills(el.ovrigePills, OVRIGE_VIS, valgtOvrige, function (p) { return p.vaerdi; }, toggleOvrige); } function toggleVaekstform(v) { var idx = valgtVaekstform.indexOf(v); if (idx === -1) valgtVaekstform.push(v); else valgtVaekstform.splice(idx, 1); renderVaekstformPills(); render(); } function renderVaekstformPills() { renderFlervalgPills(el.vaekstformPills, VAEKSTFORM_VIS, valgtVaekstform, function (p) { return p.vaerdi; }, toggleVaekstform); } function toggleBladfarve(v) { var idx = valgtBladfarve.indexOf(v); if (idx === -1) valgtBladfarve.push(v); else valgtBladfarve.splice(idx, 1); renderBladfarvePills(); render(); } function renderBladfarvePills() { renderFlervalgPills(el.bladfarvePills, BLADFARVE_VIS, valgtBladfarve, function (p) { return p.vaerdi; }, toggleBladfarve); } function toggleEfteraarsloev(v) { var idx = valgtEfteraarsloev.indexOf(v); if (idx === -1) valgtEfteraarsloev.push(v); else valgtEfteraarsloev.splice(idx, 1); renderEfteraarsloevPills(); render(); } function renderEfteraarsloevPills() { renderFlervalgPills(el.efteraarsloevPills, EFTERAARSLOEV_VIS, valgtEfteraarsloev, function (p) { return p.vaerdi; }, toggleEfteraarsloev); } function toggleLys(v) { var idx = valgtLys.indexOf(v); if (idx === -1) valgtLys.push(v); else valgtLys.splice(idx, 1); renderLysPills(); render(); } function renderLysPills() { renderFlervalgPills(el.lysPills, LYS_VIS, valgtLys, function (p) { return p.key; }, toggleLys); } function toggleJord(v) { valgtJord = (valgtJord === v) ? null : v; jordvalgFed = null; renderJordPills(); render(); if (sidsteValgt.length) beregn(); } function renderJordPills() { el.jordPills.innerHTML = JORD_VIS.map(function (p) { var aktiv = valgtJord === p.key; return ''; }).join(''); Array.prototype.forEach.call(el.jordPills.querySelectorAll('.ptv-bw-pill'), function (btn) { btn.addEventListener('click', function () { toggleJord(btn.getAttribute('data-v')); }); }); } function toggleSaeson(v) { var idx = valgtSaeson.indexOf(v); if (idx === -1) valgtSaeson.push(v); else valgtSaeson.splice(idx, 1); renderSaesonPills(); render(); } function renderSaesonPills() { renderFlervalgPills(el.saesonPills, SAESON_VIS, valgtSaeson, function (p) { return p.key; }, toggleSaeson); } function renderFilterFields() { el.farveField.hidden = FARVE_VIS.length === 0; el.lysField.hidden = LYS_VIS.length === 0; el.jordField.hidden = JORD_VIS.length === 0; el.hoejdeField.hidden = HOEJDE_VIS.length === 0; el.saesonField.hidden = SAESON_VIS.length === 0; el.anvendelseField.hidden = ANVENDELSE_VIS.length === 0; el.ovrigeField.hidden = OVRIGE_VIS.length === 0; el.vaekstformField.hidden = VAEKSTFORM_VIS.length === 0; el.bladfarveField.hidden = BLADFARVE_VIS.length === 0; el.efteraarsloevField.hidden = EFTERAARSLOEV_VIS.length === 0; applyFieldWidth(el.farveField, FARVE_VIS); applyFieldWidth(el.lysField, LYS_VIS); applyFieldWidth(el.jordField, JORD_VIS); applyFieldWidth(el.hoejdeField, HOEJDE_VIS); applyFieldWidth(el.saesonField, SAESON_VIS); applyFieldWidth(el.anvendelseField, ANVENDELSE_VIS); applyFieldWidth(el.ovrigeField, OVRIGE_VIS); applyFieldWidth(el.vaekstformField, VAEKSTFORM_VIS); applyFieldWidth(el.bladfarveField, BLADFARVE_VIS); applyFieldWidth(el.efteraarsloevField, EFTERAARSLOEV_VIS); renderFarvePills(); renderLysPills(); renderJordPills(); renderHoejdePills(); renderSaesonPills(); renderAnvendelsePills(); renderOvrigePills(); renderVaekstformPills(); renderBladfarvePills(); renderEfteraarsloevPills(); } function computeUsedFilterSets(kandidater) { var farve = [], hoejde = [], saeson = [], anvendelse = [], ovrige = [], lys = [], jord = [], vaekstform = [], bladfarve = [], efteraarsloev = []; kandidater.forEach(function (p) { p.farve_ids.forEach(function (id) { if (farve.indexOf(id) === -1) farve.push(id); }); p.hoejde_ids.forEach(function (id) { if (hoejde.indexOf(id) === -1) hoejde.push(id); }); p.anvendelse_ids.forEach(function (id) { if (anvendelse.indexOf(id) === -1) anvendelse.push(id); }); p.ovrige_ids.forEach(function (id) { if (ovrige.indexOf(id) === -1) ovrige.push(id); }); p.vaekstform_ids.forEach(function (id) { if (vaekstform.indexOf(id) === -1) vaekstform.push(id); }); p.bladfarve_ids.forEach(function (id) { if (bladfarve.indexOf(id) === -1) bladfarve.push(id); }); p.efteraarsloev_ids.forEach(function (id) { if (efteraarsloev.indexOf(id) === -1) efteraarsloev.push(id); }); var jordBucket = JORD_BUCKET[p.jord_id]; if (jordBucket && jord.indexOf(jordBucket) === -1) jord.push(jordBucket); SAESON_PILLS.forEach(function (pill) { if (saeson.indexOf(pill.key) !== -1) return; var set = SAESON_MATCH[pill.key] || []; if (set.indexOf(p.blomstring_id) !== -1) saeson.push(pill.key); }); LYS_PILLS.forEach(function (pill) { if (lys.indexOf(pill.key) !== -1) return; var set = LYS_MATCH[pill.key] || []; if (set.indexOf(p.lys_id) !== -1) lys.push(pill.key); }); }); return { farve: FARVE_PILLS.filter(function (p) { return farve.indexOf(p.vaerdi) !== -1; }), hoejde: HOEJDE_PILLS.filter(function (p) { return hoejde.indexOf(p.vaerdi) !== -1; }), saeson: SAESON_PILLS.filter(function (p) { return saeson.indexOf(p.key) !== -1; }), anvendelse: ANVENDELSE_PILLS.filter(function (p) { return anvendelse.indexOf(p.vaerdi) !== -1; }), ovrige: OVRIGE_PILLS.filter(function (p) { return ovrige.indexOf(p.vaerdi) !== -1; }), lys: LYS_PILLS.filter(function (p) { return lys.indexOf(p.key) !== -1; }), jord: JORD_PILLS.filter(function (p) { return jord.indexOf(p.key) !== -1; }), vaekstform: VAEKSTFORM_PILLS.filter(function (p) { return vaekstform.indexOf(p.vaerdi) !== -1; }), bladfarve: BLADFARVE_PILLS.filter(function (p) { return bladfarve.indexOf(p.vaerdi) !== -1; }), efteraarsloev: EFTERAARSLOEV_PILLS.filter(function (p) { return efteraarsloev.indexOf(p.vaerdi) !== -1; }) }; } function unionMatchSet(map, keys) { var out = []; keys.forEach(function (k) { var set = map[k] || []; set.forEach(function (id) { if (out.indexOf(id) === -1) out.push(id); }); }); return out; } function matchFilter(p) { if (valgtLys.length) { var lysSet = unionMatchSet(LYS_MATCH, valgtLys); if (lysSet.indexOf(p.lys_id) === -1) return false; } if (valgtJord) { var bucket = JORD_BUCKET[p.jord_id]; if (bucket !== valgtJord) return false; } if (valgtFarver.length) { if (!p.farve_ids.some(function (id) { return valgtFarver.indexOf(id) !== -1; })) return false; } if (valgtHoejde.length) { if (!p.hoejde_ids.some(function (id) { return valgtHoejde.indexOf(id) !== -1; })) return false; } if (valgtSaeson.length) { var saesonSet = unionMatchSet(SAESON_MATCH, valgtSaeson); if (saesonSet.indexOf(p.blomstring_id) === -1) return false; } if (valgtAnvendelse.length) { if (!p.anvendelse_ids.some(function (id) { return valgtAnvendelse.indexOf(id) !== -1; })) return false; } if (valgtOvrige.length) { if (!p.ovrige_ids.some(function (id) { return valgtOvrige.indexOf(id) !== -1; })) return false; } if (valgtVaekstform.length) { if (!p.vaekstform_ids.some(function (id) { return valgtVaekstform.indexOf(id) !== -1; })) return false; } if (valgtBladfarve.length) { if (!p.bladfarve_ids.some(function (id) { return valgtBladfarve.indexOf(id) !== -1; })) return false; } if (valgtEfteraarsloev.length) { if (!p.efteraarsloev_ids.some(function (id) { return valgtEfteraarsloev.indexOf(id) !== -1; })) return false; } return true; } function effectiveVarenrTrin(p) { return { varenr: p.varenr, trin: p.trin }; } function beregnMaengder(valgt, arealTotal) { var antalArter = valgt.length; var arealPrArt = antalArter > 0 ? arealTotal / antalArter : 0; return valgt.map(function (p) { var antalPlanter = Math.max(1, Math.round(arealPrArt * p.taethed_pr_m2)); var eff = effectiveVarenrTrin(p); var enhedsPris = findPris(eff.trin, antalPlanter) || 0; return { plante: p, varenr: eff.varenr, antalPlanter: antalPlanter, enhedsPris: enhedsPris, prisTotal: antalPlanter * enhedsPris }; }); } function renderResultat(sammensaetning) { el.resultatTitel.textContent = sammensaetning.length + ' prydbuske i dit bed:'; el.resultatListe.innerHTML = sammensaetning.map(function (item) { var p = item.plante; var imgHtml = p.billede ? '' : '
🌱
'; var pris = fmtKr(item.prisTotal * DATA.moms_faktor) + ' kr'; return '
' + imgHtml + '
' + '
' + p.navn + '
' + '
' + p.navn_botanisk + '
' + '
' + item.antalPlanter + ' stk' + (p.taethed_estimeret ? ' · estimeret tæthed' : '') + '
' + '
' + '
' + pris + '
' + '
'; }).join(''); } function findTilvalgByKey(key) { var liste = (DATA.tilvalg || []).filter(function (t) { return t.key === key; }); return liste.length ? liste[0] : null; } function beregnFedJordPoser(areal, plantejordData) { var bagLiter = plantejordData.bagLiter; var poserHele = Math.ceil((areal * 0.15 * 1000) / bagLiter); var antalHullerEstimat = Math.ceil(areal * plantejordData.hulleDensitet); var poserHuller = Math.ceil((antalHullerEstimat * 0.15 * 0.15 * 0.15 * 1000) / bagLiter); return { poserHele: poserHele, poserHuller: poserHuller }; } function jordforbedringLinje() { var areal = getAreal(); if (areal <= 0 || !sidsteValgt.length) return null; var plantejord = findTilvalgByKey('plantejord'); if (!plantejord) return null; var type = valgtJord ? JORD_TIL_TYPE[valgtJord] : null; if (type === 'fed_jord') { if (!jordvalgFed) return null; var poserFed = beregnFedJordPoser(areal, plantejord); if (jordvalgFed === 'huller') { return { navn: plantejord.navn + ' (kun plantehuller)', billede: plantejord.billede, varenr: plantejord.varenr, trin: plantejord.trin, antal: poserFed.poserHuller, tekst: 'Fugtig jord: vi anbefaler at forbedre kun plantehullerne (billigst) med Plantetorvets Plantejord.' }; } return { navn: plantejord.navn + ' (hele arealet)', billede: plantejord.billede, varenr: plantejord.varenr, trin: plantejord.trin, antal: poserFed.poserHele, tekst: 'Fugtig jord: vi anbefaler at forbedre hele arealet (sikrest) med Plantetorvets Plantejord.' }; } return null; } function tilvalgTotal() { var sum = 0; var jl = jordforbedringLinje(); if (jl && valgteTilvalg.plantejord && valgteTilvalg.plantejord.checked) { sum += jl.antal * (findPris(jl.trin, jl.antal) || 0); } ['godning', 'felco', 'ukrudtsdug'].forEach(function (key) { var produkt = findTilvalgByKey(key); var state = valgteTilvalg[key]; if (produkt && state && state.checked) { var qty = Math.max(1, state.qty || 1); sum += qty * (findPris(produkt.trin, qty) || 0); } }); return sum; } function updatePricebar() { var bedTotal = sidsteValgt.reduce(function (sum, item) { return sum + item.prisTotal; }, 0); var tvTotal = tilvalgTotal(); var total = (bedTotal + tvTotal) * DATA.moms_faktor; el.pricebar.innerHTML = '
' + fmtKr(total) + ' kr
' + 'i alt inkl. moms' + (tvTotal > 0 ? ' (inkl. tilvalg)' : '') + ''; } function simpleTilvalgRowHtml(key, emoji) { var produkt = findTilvalgByKey(key); if (!produkt) return ''; var state = valgteTilvalg[key] || { checked: false, qty: 1 }; var qty = Math.max(1, state.qty || 1); var enhedsPris = findPris(produkt.trin, qty) || 0; var imgHtml = produkt.billede ? '' : '
' + emoji + '
'; return ''; } function renderTilvalg() { if (!DATA || !DATA.tilvalg || DATA.tilvalg.length === 0) { el.tilvalgSection.hidden = true; return; } el.tilvalgSection.hidden = false; var rows = ''; if (valgtJord && JORD_TIL_TYPE[valgtJord] === 'fed_jord') { rows += '
' + '
Fugtig jord: vælg hvordan Jordforbedring skal beregnes.
' + '
' + '' + '' + '
'; } var jl = jordforbedringLinje(); if (jl) { var jChecked = valgteTilvalg.plantejord === undefined ? true : !!valgteTilvalg.plantejord.checked; valgteTilvalg.plantejord = { checked: jChecked }; var jTotal = jl.antal * (findPris(jl.trin, jl.antal) || 0) * DATA.moms_faktor; var jImgHtml = jl.billede ? '' : '
' + TILVALG_LABELS.plantejord + '
'; rows += ''; } rows += simpleTilvalgRowHtml('godning', TILVALG_LABELS.godning); rows += simpleTilvalgRowHtml('felco', TILVALG_LABELS.felco); rows += simpleTilvalgRowHtml('ukrudtsdug', TILVALG_LABELS.ukrudtsdug); el.tilvalgListe.innerHTML = rows; Array.prototype.forEach.call(el.tilvalgListe.querySelectorAll('[data-jordvalg]'), function (btn) { btn.addEventListener('click', function () { jordvalgFed = btn.getAttribute('data-jordvalg'); renderTilvalg(); updatePricebar(); }); }); Array.prototype.forEach.call(el.tilvalgListe.querySelectorAll('input[type=checkbox]'), function (cb) { cb.addEventListener('change', function () { var key = cb.getAttribute('data-tv'); valgteTilvalg[key] = valgteTilvalg[key] || { qty: 1 }; valgteTilvalg[key].checked = cb.checked; updatePricebar(); }); }); Array.prototype.forEach.call(el.tilvalgListe.querySelectorAll('.ptv-bw-tilvalg-qty'), function (inp) { inp.addEventListener('input', function () { var key = inp.getAttribute('data-tvqty'); valgteTilvalg[key] = valgteTilvalg[key] || { checked: false }; valgteTilvalg[key].qty = Math.max(1, parseInt(inp.value, 10) || 1); renderTilvalg(); updatePricebar(); }); }); } function updateSelectedCount() { var n = Object.keys(valgteProdukter).length; el.selectedCount.textContent = n > 0 ? n + ' produkt' + (n === 1 ? '' : 'er') + ' valgt' : ''; } function renderGrid(pool) { if (pool.length === 0) { el.grid.innerHTML = '
Ingen prydbuske matcher dine filtre.
'; return; } el.grid.innerHTML = pool.map(function (p) { var checked = !!valgteProdukter[p.plante_id]; var imgHtml = p.billede ? '' : '
🌱
'; return '
' + '
' + (checked ? '✓' : '') + '
' + imgHtml + '
' + p.navn + '
' + '
' + p.navn_botanisk + '
' + '
'; }).join(''); Array.prototype.forEach.call(el.grid.querySelectorAll('.ptv-bw-card'), function (card) { card.addEventListener('click', function () { var id = parseInt(card.getAttribute('data-id'), 10); if (valgteProdukter[id]) delete valgteProdukter[id]; else valgteProdukter[id] = true; card.classList.toggle('ptv-bw-checked'); card.querySelector('.ptv-bw-card-check').textContent = valgteProdukter[id] ? '✓' : ''; updateSelectedCount(); opdaterVaelgAlleBtn(pool); }); }); } function vaelgAlleAktiv(pool) { return pool.length > 0 && pool.every(function (p) { return !!valgteProdukter[p.plante_id]; }); } function opdaterVaelgAlleBtn(pool) { if (!el.vaelgAlleBtn) return; if (pool.length === 0) { el.vaelgAlleBtn.hidden = true; return; } el.vaelgAlleBtn.hidden = false; el.vaelgAlleBtn.textContent = vaelgAlleAktiv(pool) ? 'Fravælg alle' : 'Vælg alle'; } function toggleVaelgAlle() { var pool = DATA.kandidater.filter(matchFilter); if (vaelgAlleAktiv(pool)) { pool.forEach(function (p) { delete valgteProdukter[p.plante_id]; }); } else { pool.forEach(function (p) { valgteProdukter[p.plante_id] = true; }); } renderGrid(pool); updateSelectedCount(); opdaterVaelgAlleBtn(pool); } function render() { if (!DATA) return; var pool = DATA.kandidater.filter(matchFilter); el.matchCount.textContent = pool.length + ' prydbuske matcher dine filtre'; el.empty.hidden = pool.length !== 0; renderGrid(pool); updateSelectedCount(); opdaterVaelgAlleBtn(pool); } function visResultat(sammensaetning) { sidsteValgt = sammensaetning; renderResultat(sammensaetning); el.resultat.hidden = false; renderTilvalg(); updatePricebar(); el.pricebar.hidden = false; el.cta.hidden = false; el.disclaimer.hidden = false; el.hint.hidden = true; } function skjulResultat(besked) { sidsteValgt = []; el.resultat.hidden = true; el.tilvalgSection.hidden = true; el.pricebar.hidden = true; el.cta.hidden = true; el.disclaimer.hidden = true; if (besked) { el.hint.hidden = false; el.hint.textContent = besked; } } function beregn() { var areal = getAreal(); var valgtePlanter = DATA.kandidater.filter(function (p) { return valgteProdukter[p.plante_id]; }); if (valgtePlanter.length === 0) { skjulResultat('Marker mindst én busk i listen ovenfor for at beregne.'); return; } if (areal <= 0) { skjulResultat('Angiv arealet i m² for at beregne mængde og pris.'); return; } visResultat(beregnMaengder(valgtePlanter, areal)); } function fetchData() { fetch(DATA_URL).then(function (r) { return r.json(); }).then(function (json) { if (!json || !json.ok) { el.loading.textContent = 'Kunne ikke hente prydbuske lige nu. Prøv at genindlæse siden.'; return; } DATA = json; el.loading.hidden = true; el.body.hidden = false; var vis = computeUsedFilterSets(DATA.kandidater); FARVE_VIS = vis.farve; LYS_VIS = vis.lys; JORD_VIS = vis.jord; HOEJDE_VIS = vis.hoejde; SAESON_VIS = vis.saeson; ANVENDELSE_VIS = vis.anvendelse; OVRIGE_VIS = vis.ovrige; VAEKSTFORM_VIS = vis.vaekstform; BLADFARVE_VIS = vis.bladfarve; EFTERAARSLOEV_VIS = vis.efteraarsloev; renderFilterFields(); render(); }).catch(function () { el.loading.textContent = 'Kunne ikke hente prydbuske lige nu. Prøv at genindlæse siden.'; }); } el.head.addEventListener('click', function () { ROOT.classList.toggle('ptv-collapsed'); }); el.areal.addEventListener('input', function () { if (sidsteValgt.length) beregn(); }); el.arealMinus.addEventListener('click', function () { el.areal.value = Math.max(0.5, (parseFloat(el.areal.value) || 1) - 0.5); if (sidsteValgt.length) beregn(); }); el.arealPlus.addEventListener('click', function () { el.areal.value = (parseFloat(el.areal.value) || 0) + 0.5; if (sidsteValgt.length) beregn(); }); el.beregnBtn.addEventListener('click', beregn); el.beregnBtnTop.addEventListener('click', beregn); el.vaelgAlleBtn.addEventListener('click', toggleVaelgAlle); el.cta.addEventListener('click', function () { var items = sidsteValgt.map(function (item) { return { vareNr: item.varenr, quantity: item.antalPlanter }; }); var jl = jordforbedringLinje(); if (jl && valgteTilvalg.plantejord && valgteTilvalg.plantejord.checked) { items.push({ vareNr: jl.varenr, quantity: jl.antal }); } ['godning', 'felco', 'ukrudtsdug'].forEach(function (key) { var produkt = findTilvalgByKey(key); var state = valgteTilvalg[key]; if (produkt && state && state.checked) { items.push({ vareNr: produkt.varenr, quantity: Math.max(1, state.qty || 1) }); } }); if (!items.length) return; el.cta.disabled = true; el.status.className = 'ptv-bw-status'; el.status.textContent = 'Opretter kurv…'; fetch(KURV_URL, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ items: items }) }) .then(function (r) { return r.json(); }) .then(function (res) { el.cta.disabled = false; if (res && res.success && res.url) { el.status.className = 'ptv-bw-status ptv-ok'; el.status.innerHTML = 'Kurv oprettet — sender dig til kurven…'; try { var topWin = window.top || window.parent || window; topWin.location.href = res.url; } catch (e) { el.status.innerHTML = 'Kurv oprettet — gå til kurv →'; } } else { el.status.className = 'ptv-bw-status ptv-error'; el.status.textContent = 'Kunne ikke oprette kurven automatisk. Prøv igen om lidt.'; } }) .catch(function () { el.cta.disabled = false; el.status.className = 'ptv-bw-status ptv-error'; el.status.textContent = 'Kunne ikke oprette kurven automatisk. Prøv igen om lidt.'; }); }); fetchData(); }); })();