Android Radio Konfigurator: Unterschied zwischen den Versionen

Aus Wiki rund um Android-Navis für BMW E38/E39/E46/E53
Wechseln zu: Navigation, Suche
Zeile 1: Zeile 1:
<html><script>document.write("JS läuft");</script></html>
<html><script>document.write("JS läuft");</script></html>


<html><div id="nvk">
<html>
<div id="nvk">
<style>
<style>
#nvk{max-width:900px;line-height:1.45}
#nvk{max-width:900px;line-height:1.45}
Zeile 23: Zeile 24:
#nvk .nvk-miss{opacity:.8;font-style:italic}
#nvk .nvk-miss{opacity:.8;font-style:italic}
</style>
</style>
<div class="nvk-grid" id="nvk-fields"></div>
<div class="nvk-grid" id="nvk-fields"></div>
<fieldset id="nvk-optset"><legend>Zusatzoptionen</legend><div id="nvk-opts"></div></fieldset>
<fieldset id="nvk-optset"><legend>Zusatzoptionen</legend><div id="nvk-opts"></div></fieldset>
Zeile 29: Zeile 29:
<div id="nvk-out" aria-live="polite"></div>
<div id="nvk-out" aria-live="polite"></div>
<noscript>Für den Konfigurator wird JavaScript benötigt.</noscript>
<noscript>Für den Konfigurator wird JavaScript benötigt.</noscript>
<script>
<script>
(function () {
(function () {
"use strict";
"use strict";
/* =====================================================================
/* =====================================================================
   KONFIGURATION – hier wird gepflegt. Kein weiterer Code nötig.
   KONFIGURATION – hier wird gepflegt. Kein weiterer Code nötig.
   ===================================================================== */
   ===================================================================== */
/* ---- 1) Auswahlfelder -------------------------------------------------
/* ---- 1) Auswahlfelder -------------------------------------------------
   v = interner Wert, t = Anzeigetext,
   v = interner Wert, t = Anzeigetext,
Zeile 46: Zeile 43:
     { v: "E38", t: "BMW E38" }, { v: "E39", t: "BMW E39" }, { v: "E46", t: "BMW E46" },
     { v: "E38", t: "BMW E38" }, { v: "E39", t: "BMW E39" }, { v: "E46", t: "BMW E46" },
     { v: "E53", t: "BMW E53" }, { v: "E83", t: "BMW E83" } ] },
     { v: "E53", t: "BMW E53" }, { v: "E83", t: "BMW E83" } ] },
   { id: "factory", label: "Verbaut ab Werk", values: [
   { id: "factory", label: "Verbaut ab Werk", values: [
     { v: "iris",  t: "Radio mit IRIS" },
     { v: "iris",  t: "Radio mit IRIS" },
Zeile 53: Zeile 49:
     { v: "n169",  t: "16:9 Navi" },
     { v: "n169",  t: "16:9 Navi" },
     { v: "pfeil", t: "Pfeilnavi", only: { vehicle: ["E46"] } } ] },
     { v: "pfeil", t: "Pfeilnavi", only: { vehicle: ["E46"] } } ] },
   { id: "trunk", label: "Befindet sich im Kofferraum ein Radiomodul?",
   { id: "trunk", label: "Befindet sich im Kofferraum ein Radiomodul?",
     show: { factory: ["pfeil"] }, values: [
     show: { factory: ["pfeil"] }, values: [
Zeile 59: Zeile 54:
     { v: "nein", t: "Nein, Anschlüsse nur hinter dem Radio" },
     { v: "nein", t: "Nein, Anschlüsse nur hinter dem Radio" },
     { v: "unk", t: "Weiß ich nicht" } ] },
     { v: "unk", t: "Weiß ich nicht" } ] },
   { id: "sound", label: "Soundsystem", values: [
   { id: "sound", label: "Soundsystem", values: [
     { v: "stereo", t: "Stereo" },
     { v: "stereo", t: "Stereo" },
Zeile 65: Zeile 59:
     { v: "dsp",    t: "DSP",          only: { vehicle: ["E38", "E39", "E53"] } },
     { v: "dsp",    t: "DSP",          only: { vehicle: ["E38", "E39", "E53"] } },
     { v: "hk",    t: "Harman Kardon", only: { vehicle: ["E46", "E83"] } } ] },
     { v: "hk",    t: "Harman Kardon", only: { vehicle: ["E46", "E83"] } } ] },
   { id: "current", label: "Aktuell verbaut", values: [
   { id: "current", label: "Aktuell verbaut", values: [
     { v: "werk", t: "Werksradio / Werksnavi" },
     { v: "werk", t: "Werksradio / Werksnavi" },
     { v: "nach", t: "Nachrüst-Radio / -Navi" } ] },
     { v: "nach", t: "Nachrüst-Radio / -Navi" } ] },
   { id: "body", label: "Karosserie", values: [
   { id: "body", label: "Karosserie", values: [
     { v: "limo",    t: "Limousine", only: { vehicle: ["E38", "E39", "E46"] } },
     { v: "limo",    t: "Limousine", only: { vehicle: ["E38", "E39", "E46"] } },
Zeile 76: Zeile 68:
     { v: "cabrio",  t: "Cabrio",    only: { vehicle: ["E46"] } },
     { v: "cabrio",  t: "Cabrio",    only: { vehicle: ["E46"] } },
     { v: "suv",    t: "SUV",      only: { vehicle: ["E53", "E83"] } } ] },
     { v: "suv",    t: "SUV",      only: { vehicle: ["E53", "E83"] } } ] },
   { id: "ant", label: "Antennenstecker am Radio (optional)", optional: true, def: "unk", values: [
   { id: "ant", label: "Antennenstecker am Radio (optional)", optional: true, def: "unk", values: [
     { v: "unk",  t: "Weiß ich nicht" },
     { v: "unk",  t: "Weiß ich nicht" },
Zeile 82: Zeile 73:
     { v: "fakra", t: "FAKRA (eckig, „BM54“)" } ] }
     { v: "fakra", t: "FAKRA (eckig, „BM54“)" } ] }
];
];
/* ---- 2) Zusatzoptionen (Mehrfachauswahl) -----------------------------
/* ---- 2) Zusatzoptionen (Mehrfachauswahl) -----------------------------
   show    = Option nur sichtbar, wenn Bedingung passt
   show    = Option nur sichtbar, wenn Bedingung passt
Zeile 100: Zeile 90:
   { id: "tool",    t: "Einbau-Werkzeug (Kunststoffheber)", item: "tool" }
   { id: "tool",    t: "Einbau-Werkzeug (Kunststoffheber)", item: "tool" }
];
];
/* Wird eine Option durch eine Auswahl erzwungen, wird sie automatisch gesetzt. */
/* Wird eine Option durch eine Auswahl erzwungen, wird sie automatisch gesetzt. */
var FORCED = [
var FORCED = [
   { when: { sound: ["dsp"] }, opts: ["ibus"], why: "wegen DSP erforderlich" }
   { when: { sound: ["dsp"] }, opts: ["ibus"], why: "wegen DSP erforderlich" }
];
];
/* ---- 3) Artikel/Produkte ---------------------------------------------
/* ---- 3) Artikel/Produkte ---------------------------------------------
   u = Link in den Shop (leer lassen = Eintrag ohne Link)                  */
   u = Link in den Shop (leer lassen = Eintrag ohne Link)                  */
Zeile 129: Zeile 117:
   tool:    { t: "Einbau-Werkzeug (Kunststoffheber)", d: "Zum schonenden Lösen der Verkleidungen.", u: "" }
   tool:    { t: "Einbau-Werkzeug (Kunststoffheber)", d: "Zum schonenden Lösen der Verkleidungen.", u: "" }
};
};
/* ---- 4) Regeln --------------------------------------------------------
/* ---- 4) Regeln --------------------------------------------------------
   type  = "need" (Das brauchst Du) | "hint" (Hinweise)
   type  = "need" (Das brauchst Du) | "hint" (Hinweise)
Zeile 138: Zeile 125:
var RULES = [
var RULES = [
   { type: "need", when: { current: ["werk"], module: ["ja"] }, items: ["exl005", "fakra6m"] },
   { type: "need", when: { current: ["werk"], module: ["ja"] }, items: ["exl005", "fakra6m"] },
   { type: "hint", when: { current: ["nach"], module: ["ja"] },
   { type: "hint", when: { current: ["nach"], module: ["ja"] },
     html: "<b>Verlängerungen prüfen:</b> Bei einem bereits verbauten Nachrüst-Radio sollten EXL005 und FAKRA-Verlängerung schon vorhanden sein. <b>Ungeeignet</b> sind die Standard-„Quad-Lock-Verlängerung kombiniert mit Antennenverlängerung“ und die „EXL006“ (kein BUS-Signal)." },
     html: "\u003Cb\u003EVerlängerungen prüfen:\u003C/b\u003E Bei einem bereits verbauten Nachrüst-Radio sollten EXL005 und FAKRA-Verlängerung schon vorhanden sein. \u003Cb\u003EUngeeignet\u003C/b\u003E sind die Standard-„Quad-Lock-Verlängerung kombiniert mit Antennenverlängerung“ und die „EXL006“ (kein BUS-Signal)." },
   { type: "hint", when: { module: ["ja"] },
   { type: "hint", when: { module: ["ja"] },
     html: "<b>Kabelwege:</b> Die Technik sitzt im Kofferraum. Es müssen mindestens Kabel für Radioanschluss und FM-Antenne nach vorn verlegt werden. Optional zusätzlich: GPS (OEM-Antenne), Verlängerung für DAB+, Anschluss OEM-CD-Wechsler, Cinch für Subwoofer." },
     html: "\u003Cb\u003EKabelwege:\u003C/b\u003E Die Technik sitzt im Kofferraum. Es müssen mindestens Kabel für Radioanschluss und FM-Antenne nach vorn verlegt werden. Optional zusätzlich: GPS (OEM-Antenne), Verlängerung für DAB+, Anschluss OEM-CD-Wechsler, Cinch für Subwoofer." },
   { type: "hint", when: { module: ["nein"] },
   { type: "hint", when: { module: ["nein"] },
     html: "<b>Kabelwege:</b> Alle Anschlüsse befinden sich direkt hinter dem Radio, es müssen <b>keine</b> Kabel verlegt werden. Optional ggf. für: GPS (OEM-Antenne), DAB+, OEM-CD-Wechsler, Cinch für Subwoofer." },
     html: "\u003Cb\u003EKabelwege:\u003C/b\u003E Alle Anschlüsse befinden sich direkt hinter dem Radio, es müssen \u003Cb\u003Ekeine\u003C/b\u003E Kabel verlegt werden. Optional ggf. für: GPS (OEM-Antenne), DAB+, OEM-CD-Wechsler, Cinch für Subwoofer." },
   { type: "hint", when: { module: ["unk"] },
   { type: "hint", when: { module: ["unk"] },
     html: "<b>Bitte prüfen:</b> Schau nach, ob im Kofferraum ein Radiomodul sitzt. Manche E46 mit Pfeilnavi (vermutlich Vorfacelift) haben das Radio hinten und benötigen dann EXL005 + FAKRA-Verlängerung." },
     html: "\u003Cb\u003EBitte prüfen:\u003C/b\u003E Schau nach, ob im Kofferraum ein Radiomodul sitzt. Manche E46 mit Pfeilnavi (vermutlich Vorfacelift) haben das Radio hinten und benötigen dann EXL005 + FAKRA-Verlängerung." },
 
   { type: "need", when: { ant: ["iso"] }, items: ["isoada"] },
   { type: "need", when: { ant: ["iso"] }, items: ["isoada"] },
   { type: "hint", when: { ant: ["unk"] },
   { type: "hint", when: { ant: ["unk"] },
     html: "<b>Antennenstecker:</b> Hat Dein Fahrzeug einen ISO-Antennenstecker, brauchst Du zusätzlich den <a href='https://shop.ibus-app.de/shop/zubehoer/adapterkabel/193/adapter-kabel-iso-f-auf-fakra-f-kurz-gewinkelt-15cm'>Adapter ISO auf FAKRA</a>. Bei FAKRA ist kein Adapter nötig." },
     html: "\u003Cb\u003EAntennenstecker:\u003C/b\u003E Hat Dein Fahrzeug einen ISO-Antennenstecker, brauchst Du zusätzlich den \u003Ca href='https://shop.ibus-app.de/shop/zubehoer/adapterkabel/193/adapter-kabel-iso-f-auf-fakra-f-kurz-gewinkelt-15cm'\u003EAdapter ISO auf FAKRA\u003C/a\u003E. Bei FAKRA ist kein Adapter nötig." },
 
   { type: "need", when: { sound: ["dsp"] }, items: ["dsplic"] },
   { type: "need", when: { sound: ["dsp"] }, items: ["dsplic"] },
   { type: "hint", when: { sound: ["dsp"] },
   { type: "hint", when: { sound: ["dsp"] },
     html: "<b>DSP:</b> Damit das Werks-DSP überhaupt arbeitet, wird die I-BUS App mit DSP-Lizenz benötigt." },
     html: "\u003Cb\u003EDSP:\u003C/b\u003E Damit das Werks-DSP überhaupt arbeitet, wird die I-BUS App mit DSP-Lizenz benötigt." },
   { type: "hint", when: { sound: ["hk"] },
   { type: "hint", when: { sound: ["hk"] },
     html: "<b>Harman Kardon:</b> Benötigt <b>keine</b> DSP-Lizenz. Das Remote-Signal (+12 V, wenn Radio an) genügt zum Starten." },
     html: "\u003Cb\u003EHarman Kardon:\u003C/b\u003E Benötigt \u003Cb\u003Ekeine\u003C/b\u003E DSP-Lizenz. Das Remote-Signal (+12 V, wenn Radio an) genügt zum Starten." },
 
   { type: "hint", when: { vehicle: ["E38", "E53"] },
   { type: "hint", when: { vehicle: ["E38", "E53"] },
     html: "<b>Montage:</b> Radios für BMW E38/E53 benötigen keine extra Halterungen." },
     html: "\u003Cb\u003EMontage:\u003C/b\u003E Radios für BMW E38/E53 benötigen keine extra Halterungen." },
   { type: "hint", when: { vehicle: ["E39"] },
   { type: "hint", when: { vehicle: ["E39"] },
     html: "<b>Montage:</b> Bei Radios, die nicht von AVIN stammen, empfehlen wir einen Halter (siehe Zusatzoptionen) oder das Bearbeiten der beiliegenden Montagewinkel. Anleitungen: <a href='https://xtrons.ibus-app.de/index.php?title=Montageanleitungen'>Montageanleitungen</a>." },
     html: "\u003Cb\u003EMontage:\u003C/b\u003E Bei Radios, die nicht von AVIN stammen, empfehlen wir einen Halter (siehe Zusatzoptionen) oder das Bearbeiten der beiliegenden Montagewinkel. Anleitungen: \u003Ca href='https://xtrons.ibus-app.de/index.php?title=Montageanleitungen'\u003EMontageanleitungen\u003C/a\u003E." },
   { type: "hint", when: { vehicle: ["E46"], factory: ["iris", "mid", "pfeil"], current: ["werk"] },
   { type: "hint", when: { vehicle: ["E46"], factory: ["iris", "mid", "pfeil"], current: ["werk"] },
     html: "<b>Montage E46 ohne großes Navi:</b> Das Klimabedienteil muss nach unten versetzt werden. Dafür brauchst Du den passenden <b>Funktionsträger</b> (neu ca. 100 €, ggf. beim Teileverwerter günstiger):<br>" +
     html: "\u003Cb\u003EMontage E46 ohne großes Navi:\u003C/b\u003E Das Klimabedienteil muss nach unten versetzt werden. Dafür brauchst Du den passenden \u003Cb\u003EFunktionsträger\u003C/b\u003E (neu ca. 100 €, ggf. beim Teileverwerter günstiger):\u003Cbr\u003E" +
           "Einzelschalter (eher VFL): <a href='https://www.leebmann24.de/trager-3er-51168202186.html'>ohne Raucher 51168202186</a> / <a href='https://www.leebmann24.de/trager-3er-51168230902.html'>mit Raucher 51168230902</a><br>" +
           "Einzelschalter (eher VFL): \u003Ca href='https://www.leebmann24.de/trager-3er-51168202186.html'\u003Eohne Raucher 51168202186\u003C/a\u003E / \u003Ca href='https://www.leebmann24.de/trager-3er-51168230902.html'\u003Emit Raucher 51168230902\u003C/a\u003E\u003Cbr\u003E" +
           "Schaltzentrum (eher FL): <a href='https://www.leebmann24.de/funktionstrager-schaltzentrum-3er-51167001408.html'>ohne Raucher 51167001408</a> / <a href='https://www.leebmann24.de/funktionstrager-schaltzentrum-3er-51167001410.html'>mit Raucher 51167001410</a>" },
           "Schaltzentrum (eher FL): \u003Ca href='https://www.leebmann24.de/funktionstrager-schaltzentrum-3er-51167001408.html'\u003Eohne Raucher 51167001408\u003C/a\u003E / \u003Ca href='https://www.leebmann24.de/funktionstrager-schaltzentrum-3er-51167001410.html'\u003Emit Raucher 51167001410\u003C/a\u003E" },
 
   { type: "hint", opts: ["ibus"], when: {},
   { type: "hint", opts: ["ibus"], when: {},
     html: "<b>I-BUS App:</b> Siehe <a href='https://wiki.ibus-app.de/index.php?title=Was_brauche_ich_um_die_I-BUS_App_nutzen_zu_k%C3%B6nnen%3F'>Was brauche ich, um die I-BUS App nutzen zu können?</a> und die <a href='https://wiki.ibus-app.de/index.php?title=Einbauanleitung_f%C3%BCr_Resler_Modul_und_Resler_Interface'>Einbauanleitung für Resler Modul und Interface</a>." },
     html: "\u003Cb\u003EI-BUS App:\u003C/b\u003E Siehe \u003Ca href='https://wiki.ibus-app.de/index.php?title=Was_brauche_ich_um_die_I-BUS_App_nutzen_zu_k%C3%B6nnen%3F'\u003EWas brauche ich, um die I-BUS App nutzen zu können?\u003C/a\u003E und die \u003Ca href='https://wiki.ibus-app.de/index.php?title=Einbauanleitung_f%C3%BCr_Resler_Modul_und_Resler_Interface'\u003EEinbauanleitung für Resler Modul und Interface\u003C/a\u003E." },
   { type: "hint", when: {}, opts: [],
   { type: "hint", when: {}, opts: [],
     html: "<b>Wichtig:</b> Bitte immer die Anschlüsse am eigenen Radio abgleichen. Welches Radio passt? → <a href='https://xtrons.ibus-app.de/index.php?title=Entscheidungshilfe%3A_AVIN_oder_XTRONS%3F'>Entscheidungshilfe AVIN oder XTRONS</a>, Kosten → <a href='https://xtrons.ibus-app.de/index.php?title=Grobe_Kosten%C3%BCbersicht'>Grobe Kostenübersicht</a>." }
     html: "\u003Cb\u003EWichtig:\u003C/b\u003E Bitte immer die Anschlüsse am eigenen Radio abgleichen. Welches Radio passt? → \u003Ca href='https://xtrons.ibus-app.de/index.php?title=Entscheidungshilfe%3A_AVIN_oder_XTRONS%3F'\u003EEntscheidungshilfe AVIN oder XTRONS\u003C/a\u003E, Kosten → \u003Ca href='https://xtrons.ibus-app.de/index.php?title=Grobe_Kosten%C3%BCbersicht'\u003EGrobe Kostenübersicht\u003C/a\u003E." }
];
];
/* =====================================================================
/* =====================================================================
   PROGRAMMLOGIK
   PROGRAMMLOGIK
Zeile 179: Zeile 160:
var sel = {}, picked = {};
var sel = {}, picked = {};
var fieldsEl = $("nvk-fields"), optsEl = $("nvk-opts"), outEl = $("nvk-out");
var fieldsEl = $("nvk-fields"), optsEl = $("nvk-opts"), outEl = $("nvk-out");
function match(cond, s, lenient) {
function match(cond, s, lenient) {
   if (!cond) return true;
   if (!cond) return true;
   for (var k in cond) {
   for (var k in cond) {
     if (!s[k]) { if (lenient) continue; return false; }
     if (!s[k]) { if (lenient) continue; return false; }
     if (cond[k].indexOf(s[k]) < 0) return false;
     if (cond[k].indexOf(s[k]) === -1) return false;
   }
   }
   return true;
   return true;
Zeile 211: Zeile 191:
   return (o.requires || []).every(function (r) { return on[r]; });
   return (o.requires || []).every(function (r) { return on[r]; });
}
}
/* Felder aufbauen */
/* Felder aufbauen */
FIELDS.forEach(function (f) {
FIELDS.forEach(function (f) {
Zeile 220: Zeile 199:
   wrap.appendChild(lab); wrap.appendChild(s); fieldsEl.appendChild(wrap);
   wrap.appendChild(lab); wrap.appendChild(s); fieldsEl.appendChild(wrap);
});
});
function renderFields() {
function renderFields() {
   var s = derive();
   var s = derive();
Zeile 229: Zeile 207:
     if (!vis) { sel[f.id] = ""; return; }
     if (!vis) { sel[f.id] = ""; return; }
     var allowed = f.values.filter(function (v) { return match(v.only, s, true); });
     var allowed = f.values.filter(function (v) { return match(v.only, s, true); });
     if (sel[f.id] && !allowed.some(function (v) { return v.v === sel[f.id]; })) sel[f.id] = "";
     if (sel[f.id] ? !allowed.some(function (v) { return v.v === sel[f.id]; }) : false) sel[f.id] = "";
     if (!sel[f.id] && f.def) sel[f.id] = f.def;
     if (!sel[f.id]) { if (f.def) sel[f.id] = f.def; }
     el.innerHTML = "";
     el.innerHTML = "";
     if (!f.def) { var p = document.createElement("option"); p.value = ""; p.textContent = "– bitte wählen –"; el.appendChild(p); }
     if (!f.def) { var p = document.createElement("option"); p.value = ""; p.textContent = "– bitte wählen –"; el.appendChild(p); }
Zeile 239: Zeile 217:
   });
   });
}
}
function renderOpts() {
function renderOpts() {
   var s = derive(), st = onSet(s);
   var s = derive(), st = onSet(s);
   /* Gruppen-Ausschluss & nicht mehr sichtbare Optionen bereinigen */
   /* Gruppen-Ausschluss und nicht mehr sichtbare Optionen bereinigen */
   OPTS.forEach(function (o) { if (!optVisible(o, s, st.on)) picked[o.id] = false; });
   OPTS.forEach(function (o) { if (!optVisible(o, s, st.on)) picked[o.id] = false; });
   st = onSet(s);
   st = onSet(s);
Zeile 255: Zeile 232:
     cb.addEventListener("change", function () {
     cb.addEventListener("change", function () {
       picked[o.id] = cb.checked;
       picked[o.id] = cb.checked;
       if (cb.checked && o.excl) OPTS.forEach(function (x) { if (x.excl === o.excl && x.id !== o.id) picked[x.id] = false; });
       if (cb.checked) { if (o.excl) OPTS.forEach(function (x) { if (x.excl === o.excl) { if (x.id !== o.id) picked[x.id] = false; } }); }
       update();
       update();
     });
     });
Zeile 266: Zeile 243:
   });
   });
}
}
function card(item, cls) {
function card(item, cls) {
   var d = document.createElement("div"); d.className = "nvk-card " + (cls || "");
   var d = document.createElement("div"); d.className = "nvk-card " + (cls || "");
Zeile 277: Zeile 253:
   return d;
   return d;
}
}
function renderResult() {
function renderResult() {
   var s = derive(), st = onSet(s);
   var s = derive(), st = onSet(s);
Zeile 292: Zeile 267:
   RULES.forEach(function (r) {
   RULES.forEach(function (r) {
     if (!match(r.when, s)) return;
     if (!match(r.when, s)) return;
     if (r.opts && !r.opts.every(function (o) { return st.on[o]; })) return;
     if (r.opts) { if (!r.opts.every(function (o) { return st.on[o]; })) return; }
     if (r.type === "need") (r.items || []).forEach(function (id) { if (!seen[id]) { seen[id] = 1; needs.push(ITEMS[id]); } });
     if (r.type === "need") (r.items || []).forEach(function (id) { if (!seen[id]) { seen[id] = 1; needs.push(ITEMS[id]); } });
     else hints.push(r.html);
     else hints.push(r.html);
Zeile 299: Zeile 274:
   if (needs.length) needs.forEach(function (i) { outEl.appendChild(card(i)); });
   if (needs.length) needs.forEach(function (i) { outEl.appendChild(card(i)); });
   else { var n = document.createElement("p"); n.textContent = "Für die Grundinstallation sind keine zusätzlichen Verlängerungen oder Adapter nötig."; outEl.appendChild(n); }
   else { var n = document.createElement("p"); n.textContent = "Für die Grundinstallation sind keine zusätzlichen Verlängerungen oder Adapter nötig."; outEl.appendChild(n); }
   var opt = [];
   var opt = [];
   OPTS.forEach(function (o) { if (st.on[o.id] && optVisible(o, s, st.on) && !seen[o.item]) opt.push(ITEMS[o.item]); });
   OPTS.forEach(function (o) { if (st.on[o.id]) { if (optVisible(o, s, st.on)) { if (!seen[o.item]) opt.push(ITEMS[o.item]); } } });
   if (opt.length) {
   if (opt.length) {
     var h2 = document.createElement("h3"); h2.textContent = "Deine Zusatzoptionen"; outEl.appendChild(h2);
     var h2 = document.createElement("h3"); h2.textContent = "Deine Zusatzoptionen"; outEl.appendChild(h2);
Zeile 311: Zeile 285:
   }
   }
}
}
function update() { renderFields(); renderOpts(); renderResult(); }
function update() { renderFields(); renderOpts(); renderResult(); }
$("nvk-reset").addEventListener("click", function () { sel = {}; picked = {}; update(); });
$("nvk-reset").addEventListener("click", function () { sel = {}; picked = {}; update(); });
Zeile 318: Zeile 291:
</script>
</script>
</div>
</div>
</html>
</html>

Version vom 21. Oktober 2026, 09:55 Uhr

Zusatzoptionen