|
|
| Zeile 1: |
Zeile 1: |
| | <!DOCTYPE html> |
| | |
| <html lang="de"> | | <html lang="de"> |
| <head> | | <head> |
| <meta charset="UTF-8"> | | <meta charset="UTF-8"> |
| <meta name="viewport" content="width=device-width, initial-scale=1.0">
| |
| <title>Familienangebote August 2026</title> | | <title>Familienangebote August 2026</title> |
|
| |
|
| <style> | | <style> |
| body{ | | body { |
| font-family: Arial, sans-serif; | | font-family: Arial, sans-serif; |
| margin:20px; | | margin: 20px; |
| background:#f5f5f5;
| |
| } | | } |
|
| |
|
| h1{
| | h2 { |
| text-align:center; | | text-align: center; |
| } | | } |
|
| |
|
| .toolbar{ | | .calendar { |
| display:flex; | | display: grid; |
| gap:10px; | | grid-template-columns: repeat(7, 1fr); |
| margin-bottom:20px;
| | gap: 8px; |
| justify-content:center; | |
| } | | } |
|
| |
|
| button{
| | .weekday { |
| cursor:pointer; | | font-weight: bold; |
| | text-align: center; |
| | padding: 10px; |
| | background: #f0f0f0; |
| } | | } |
|
| |
|
| .calendar{ | | .day { |
| display:grid; | | border: 1px solid #ccc; |
| grid-template-columns:repeat(7,1fr); | | min-height: 120px; |
| gap:10px; | | padding: 8px; |
| | cursor: pointer; |
| | background: #fff; |
| | transition: 0.2s; |
| } | | } |
|
| |
|
| .weekday{ | | .day:hover { |
| background:#003366; | | background: #f8f8f8; |
| color:white;
| |
| padding:10px;
| |
| text-align:center;
| |
| font-weight:bold;
| |
| } | | } |
|
| |
|
| .day{ | | .day-number { |
| background:white; | | font-weight: bold; |
| min-height:150px;
| | margin-bottom: 5px; |
| border-radius:8px;
| |
| padding:8px; | |
| box-shadow:0 2px 5px rgba(0,0,0,.15);
| |
| cursor:pointer;
| |
| } | | } |
|
| |
|
| .day-number{ | | .note { |
| font-weight:bold;
| | font-size: 13px; |
| margin-bottom:8px;
| | white-space: pre-wrap; |
| }
| |
| | |
| .entry{
| |
| background:#e8f2ff;
| |
| padding:4px;
| |
| margin-bottom:4px;
| |
| border-radius:4px;
| |
| font-size:12px; | |
| }
| |
| | |
| .modal{
| |
| display:none;
| |
| position:fixed; | |
| inset:0;
| |
| background:rgba(0,0,0,.5);
| |
| justify-content:center;
| |
| align-items:center;
| |
| }
| |
| | |
| .modal-content{
| |
| background:white;
| |
| width:90%;
| |
| max-width:900px;
| |
| max-height:90vh;
| |
| overflow:auto;
| |
| padding:20px;
| |
| border-radius:10px;
| |
| }
| |
| | |
| label{
| |
| display:block;
| |
| margin-top:10px;
| |
| font-weight:bold;
| |
| }
| |
| | |
| input, textarea{
| |
| width:100%;
| |
| padding:8px;
| |
| box-sizing:border-box;
| |
| }
| |
| | |
| .entry-card{
| |
| border:1px solid #ccc;
| |
| padding:10px;
| |
| margin:10px 0;
| |
| border-radius:6px;
| |
| }
| |
| | |
| .actions{
| |
| display:flex;
| |
| gap:10px;
| |
| margin-top:10px;
| |
| } | | } |
| | </style> |
|
| |
|
| .close-btn{
| |
| float:right;
| |
| }
| |
|
| |
| .empty{
| |
| background:transparent;
| |
| }
| |
| </style>
| |
| </head> | | </head> |
| <body> | | <body> |
|
| |
|
| <h1>Familienangebote – August 2026</h1> | | <h2>Familienangebote – August 2026</h2> |
| | |
| <div class="toolbar">
| |
| <button onclick="exportData()">Export JSON</button>
| |
| <button onclick="exportPDF()">Export PDF</button>
| |
| <button onclick="exportExcel()">Export Excel</button>
| |
| | |
| <input type="file" id="importFile" onchange="importData(event)">
| |
| </div>
| |
|
| |
|
| <div class="calendar" id="calendar"></div> | | <div class="calendar" id="calendar"></div> |
|
| |
| <div class="modal" id="modal">
| |
| <div class="modal-content">
| |
|
| |
| <button class="close-btn" onclick="closeModal()">Schließen</button>
| |
|
| |
| <h2 id="modalDate"></h2>
| |
|
| |
| <button onclick="addEntry()">+ Neuer Eintrag</button>
| |
|
| |
| <div id="entriesContainer"></div>
| |
|
| |
| </div>
| |
| </div>
| |
|
| |
|
| <script> | | <script> |
| | const calendar = document.getElementById("calendar"); |
|
| |
|
| let data = {
| | const weekdays = [ |
| "1": [
| | "Mo","Di","Mi","Do","Fr","Sa","So" |
| {
| | ]; |
| angebot: "Bächlewanderung mit Kind und Kescher",
| |
| uhrzeit: "10:00 - 13:00",
| |
| ort: "Start und Treffpunkt ist am Parkplatz Bebenhausen.",
| |
| zielgruppe: "Geeignet für Familien mit Kindern ab 5 Jahren",
| |
| anmeldung: "wird benötigt",
| |
| link: "https://www.fbs-tuebingen.de/eltern-und-kinder/kw/bereich/kursdetails/kurs/261-2516B/kursname/Baechlewanderung%20mit%20Kind%20und%20Kescher/kategorie-id/11/",
| |
| beschreibung: "Wir wandern am Goldersbach entlang über die Tellerbrücke zur Teufelsbrücke."
| |
| }
| |
| ],
| |
| | |
| "2": [
| |
| {
| |
| angebot: "Eiscafé frieDa",
| |
| uhrzeit: "14:00-17:00",
| |
| ort: "Café frieDa, Friedrich-Dannenmann-Straße 69, 72070 Tübingen",
| |
| zielgruppe: "Familien, Nachbarn, Menschen mit und ohne Behinderung",
| |
| anmeldung: "",
| |
| link: "https://www.lebenshilfe-tuebingen.de/service/termine/",
| |
| beschreibung: "Das Eiscafé frieDa ist ein Begegnungs-Ort."
| |
| },
| |
| {
| |
| angebot: "Geschwisterchen auf dem Weg",
| |
| uhrzeit: "10:00 - 12:00",
| |
| ort: "FBS, Raum 003 Villa Metz, Hechingerstraße 13",
| |
| zielgruppe: "Für Kinder ab 4 Jahren mit einem Elternteil",
| |
| anmeldung: "wird benötigt",
| |
| link: "https://www.fbs-tuebingen.de/programm/kw/bereich/kursdetails/kurs/261-2509/kursname/Geschwisterchen%20auf%20dem%20Weg/",
| |
| beschreibung: "Vorbereitung auf ein Geschwisterchen."
| |
| }
| |
| ],
| |
| | |
| "4": [
| |
| {
| |
| angebot: "BabyBrunch",
| |
| uhrzeit: "09:30-11:30",
| |
| ort: "elkiko Familienzentrum",
| |
| zielgruppe: "Eltern mit Säuglingen und Kleinkindern",
| |
| anmeldung: "babybrunch@elkiko.de",
| |
| link: "https://www.elkiko.de/content2/index.php/de/programm/babybrunch-brunch1plus.html",
| |
| beschreibung: ""
| |
| }
| |
| ],
| |
| | |
| "5": [
| |
| {
| |
| angebot: "Spielplatztreff",
| |
| uhrzeit: "14:30-15:30",
| |
| ort: "Piratenspielplatz, Anlagenpark",
| |
| zielgruppe: "Familien mit jüngeren Kindern",
| |
| anmeldung: "-",
| |
| link: "",
| |
| beschreibung: "Treffpunkt zum Austausch mit der Familienbeauftragten."
| |
| }
| |
| ],
| |
| | |
| "6": [
| |
| {
| |
| angebot: "BabyBrunch",
| |
| uhrzeit: "09:30-11:30",
| |
| ort: "elkiko Familienzentrum",
| |
| zielgruppe: "Eltern mit Säuglingen und Kleinkindern",
| |
| anmeldung: "babybrunch@elkiko.de",
| |
| link: "https://www.elkiko.de/content2/index.php/de/programm/babybrunch-brunch1plus.html",
| |
| beschreibung:
| |
| },
| |
| {
| |
| angebot: "Sommerferien mit dem LESE-HAUS",
| |
| uhrzeit: "11:00"
| |
| ort: Alter Botanischer Garten, Wiese neben dem Kinderspielplatz, bei schlechtem Wetter: Thekla-Waitz-Studio, im EG der Stadtbücherei, Nonnengasse 19, 72070 Tübingen",
| |
| zielgruppe: "Kinder von 4 - 8 Jahre mit Begleitpersonen",
| |
| link: "https://tuebingen.ferienprogramm-online.de/"
| |
| beschreibung: ""Vorlesestunde zum Thema „Unsere Welt ist bunt“ mit allerlei Geschichten, vorgelesen von Lesepatinnen und Lesepaten des LESE-HAUSes sowie Mitarbeitenden der Stadtbücherei.
| |
| Bei schönem Wetter findet die Veranstaltung immer donnerstags im Alten Botanischen Garten an einem schattigen Plätzchen statt. Bei schlechtem Wetter treffen wir uns im Thekla-Waitz-Studio im Erdgeschoss der Stadtbücherei."
| |
| | |
| | |
| | |
| | |
| }
| |
| ],
| |
| | |
| "9": [
| |
| {
| |
| angebot: "Eiscafé frieDa",
| |
| uhrzeit: "14:00-17:00",
| |
| ort: "Café frieDa, Friedrich-Dannenmann-Straße 69, 72070 Tübingen",
| |
| zielgruppe: "Familien, Nachbarn, Menschen mit und ohne Behinderung",
| |
| anmeldung: "",
| |
| link: "https://www.lebenshilfe-tuebingen.de/service/termine/",
| |
| beschreibung: "Das Eiscafé frieDa ist ein Begegnungs-Ort."
| |
| }
| |
| ],
| |
| | |
| "11": [
| |
| {
| |
| angebot: "BabyBrunch",
| |
| uhrzeit: "09:30-11:30",
| |
| ort: "elkiko Familienzentrum",
| |
| zielgruppe: "Eltern mit Säuglingen und Kleinkindern",
| |
| anmeldung: "babybrunch@elkiko.de",
| |
| link: "https://www.elkiko.de/content2/index.php/de/programm/babybrunch-brunch1plus.html",
| |
| beschreibung: ""
| |
| }
| |
| ],
| |
| | |
| "12": [
| |
| {
| |
| angebot: "Spielplatztreff",
| |
| uhrzeit: "14:30-15:30"
| |
| }
| |
| ],
| |
| | |
| "13": [
| |
| {
| |
| angebot: "BabyBrunch",
| |
| uhrzeit: "09:30-11:30",
| |
| ort: "elkiko Familienzentrum",
| |
| zielgruppe: "Eltern mit Säuglingen und Kleinkindern",
| |
| anmeldung: "babybrunch@elkiko.de",
| |
| link: "https://www.elkiko.de/content2/index.php/de/programm/babybrunch-brunch1plus.html",
| |
| beschreibung: ""
| |
| },
| |
| {
| |
| angebot: "Sommerferien mit dem LESE-HAUS",
| |
| uhrzeit: "11:00"
| |
| ort: Alter Botanischer Garten, Wiese neben dem Kinderspielplatz, bei schlechtem Wetter: Thekla-Waitz-Studio, im EG der Stadtbücherei, Nonnengasse 19, 72070 Tübingen",
| |
| zielgruppe: "Kinder von 4 - 8 Jahre mit Begleitpersonen",
| |
| link: "https://tuebingen.ferienprogramm-online.de/"
| |
| beschreibung: ""Vorlesestunde zum Thema „Unsere Welt ist bunt“ mit allerlei Geschichten, vorgelesen von Lesepatinnen und Lesepaten des LESE-HAUSes sowie Mitarbeitenden der Stadtbücherei.
| |
| Bei schönem Wetter findet die Veranstaltung immer donnerstags im Alten Botanischen Garten an einem schattigen Plätzchen statt. Bei schlechtem Wetter treffen wir uns im Thekla-Waitz-Studio im Erdgeschoss der Stadtbücherei."
| |
| }
| |
| ],
| |
| | |
| "16": [
| |
| { | |
| angebot: "Eiscafé frieDa",
| |
| uhrzeit: "14:00-17:00",
| |
| ort: "Café frieDa, Friedrich-Dannenmann-Straße 69, 72070 Tübingen",
| |
| zielgruppe: "Familien, Nachbarn, Menschen mit und ohne Behinderung",
| |
| anmeldung: "",
| |
| link: "https://www.lebenshilfe-tuebingen.de/service/termine/",
| |
| beschreibung: "Das Eiscafé frieDa ist ein Begegnungs-Ort."
| |
| },
| |
| {
| |
| angebot: "Bunt backen mit Kindern: Regenbogen-Muffins & Cake-Pops",
| |
| uhrzeit: "16:00 - 18:30"
| |
| }
| |
| ],
| |
| | |
| "18": [
| |
| {
| |
| angebot: "BabyBrunch",
| |
| uhrzeit: "09:30-11:30",
| |
| ort: "elkiko Familienzentrum",
| |
| zielgruppe: "Eltern mit Säuglingen und Kleinkindern",
| |
| anmeldung: "babybrunch@elkiko.de",
| |
| link: "https://www.elkiko.de/content2/index.php/de/programm/babybrunch-brunch1plus.html",
| |
| beschreibung: ""
| |
| }
| |
| ],
| |
| | |
| "19": [
| |
| {
| |
| angebot: "Spielplatztreff",
| |
| uhrzeit: "14:30-15:30"
| |
| }
| |
| ],
| |
| | |
| "20": [
| |
| {
| |
| angebot: "BabyBrunch",
| |
| uhrzeit: "09:30-11:30",
| |
| ort: "elkiko Familienzentrum",
| |
| zielgruppe: "Eltern mit Säuglingen und Kleinkindern",
| |
| anmeldung: "babybrunch@elkiko.de",
| |
| link: "https://www.elkiko.de/content2/index.php/de/programm/babybrunch-brunch1plus.html",
| |
| beschreibung: ""
| |
| },
| |
| {
| |
| angebot: "Sommerferien mit dem LESE-HAUS",
| |
| uhrzeit: "11:00"
| |
| ort: Alter Botanischer Garten, Wiese neben dem Kinderspielplatz, bei schlechtem Wetter: Thekla-Waitz-Studio, im EG der Stadtbücherei, Nonnengasse 19, 72070 Tübingen",
| |
| zielgruppe: "Kinder von 4 - 8 Jahre mit Begleitpersonen",
| |
| link: "https://tuebingen.ferienprogramm-online.de/"
| |
| beschreibung: ""Vorlesestunde zum Thema „Unsere Welt ist bunt“ mit allerlei Geschichten, vorgelesen von Lesepatinnen und Lesepaten des LESE-HAUSes sowie Mitarbeitenden der Stadtbücherei.
| |
| Bei schönem Wetter findet die Veranstaltung immer donnerstags im Alten Botanischen Garten an einem schattigen Plätzchen statt. Bei schlechtem Wetter treffen wir uns im Thekla-Waitz-Studio im Erdgeschoss der Stadtbücherei."
| |
| }
| |
| ],
| |
| | |
| "23": [
| |
| {
| |
| angebot: "Eiscafé frieDa",
| |
| uhrzeit: "14:00-17:00",
| |
| ort: "Café frieDa, Friedrich-Dannenmann-Straße 69, 72070 Tübingen",
| |
| zielgruppe: "Familien, Nachbarn, Menschen mit und ohne Behinderung",
| |
| anmeldung: "",
| |
| link: "https://www.lebenshilfe-tuebingen.de/service/termine/",
| |
| beschreibung: "Das Eiscafé frieDa ist ein Begegnungs-Ort."
| |
| }
| |
| ],
| |
| | |
| "25": [
| |
| {
| |
| angebot: "BabyBrunch",
| |
| uhrzeit: "09:30-11:30",
| |
| ort: "elkiko Familienzentrum",
| |
| zielgruppe: "Eltern mit Säuglingen und Kleinkindern",
| |
| anmeldung: "babybrunch@elkiko.de",
| |
| link: "https://www.elkiko.de/content2/index.php/de/programm/babybrunch-brunch1plus.html",
| |
| beschreibung: ""
| |
| }
| |
| ],
| |
| | |
| "26": [
| |
| {
| |
| angebot: "Spielplatztreff",
| |
| uhrzeit: "14:30-15:30"
| |
| }
| |
| ],
| |
| | |
| "27": [
| |
| {
| |
| angebot: "BabyBrunch",
| |
| uhrzeit: "09:30-11:30",
| |
| ort: "elkiko Familienzentrum",
| |
| zielgruppe: "Eltern mit Säuglingen und Kleinkindern",
| |
| anmeldung: "babybrunch@elkiko.de",
| |
| link: "https://www.elkiko.de/content2/index.php/de/programm/babybrunch-brunch1plus.html",
| |
| beschreibung: ""
| |
| },
| |
| {
| |
| angebot: "Sommerferien mit dem LESE-HAUS",
| |
| uhrzeit: "11:00"
| |
| ort: Alter Botanischer Garten, Wiese neben dem Kinderspielplatz, bei schlechtem Wetter: Thekla-Waitz-Studio, im EG der Stadtbücherei, Nonnengasse 19, 72070 Tübingen",
| |
| zielgruppe: "Kinder von 4 - 8 Jahre mit Begleitpersonen",
| |
| link: "https://tuebingen.ferienprogramm-online.de/"
| |
| beschreibung: ""Vorlesestunde zum Thema „Unsere Welt ist bunt“ mit allerlei Geschichten, vorgelesen von Lesepatinnen und Lesepaten des LESE-HAUSes sowie Mitarbeitenden der Stadtbücherei.
| |
| Bei schönem Wetter findet die Veranstaltung immer donnerstags im Alten Botanischen Garten an einem schattigen Plätzchen statt. Bei schlechtem Wetter treffen wir uns im Thekla-Waitz-Studio im Erdgeschoss der Stadtbücherei."
| |
| }
| |
| ],
| |
| | |
| "30": [
| |
| {
| |
| angebot: "Eiscafé frieDa",
| |
| uhrzeit: "14:00-17:00",
| |
| ort: "Café frieDa, Friedrich-Dannenmann-Straße 69, 72070 Tübingen",
| |
| zielgruppe: "Familien, Nachbarn, Menschen mit und ohne Behinderung",
| |
| anmeldung: "",
| |
| link: "https://www.lebenshilfe-tuebingen.de/service/termine/",
| |
| beschreibung: "Das Eiscafé frieDa ist ein Begegnungs-Ort."
| |
| }
| |
| ]
| |
| };
| |
| | |
| | |
| let selectedDay = null;
| |
| | |
| const weekdays = ["Mo","Di","Mi","Do","Fr","Sa","So"];
| |
| | |
| function saveData(){
| |
| renderCalendar();
| |
| }
| |
| | |
| function renderCalendar(){
| |
| | |
| const cal = document.getElementById("calendar");
| |
| cal.innerHTML = "";
| |
| | |
| weekdays.forEach(day=>{
| |
| const div = document.createElement("div");
| |
| div.className = "weekday";
| |
| div.textContent = day;
| |
| cal.appendChild(div);
| |
| });
| |
| | |
| const firstDay = new Date(2026,7,1);
| |
| | |
| let offset = firstDay.getDay();
| |
| offset = offset === 0 ? 6 : offset - 1;
| |
| | |
| for(let i=0;i<offset;i++){
| |
| const empty = document.createElement("div");
| |
| empty.className = "empty";
| |
| cal.appendChild(empty);
| |
| }
| |
| | |
| for(let day=1; day<=31; day++){
| |
| | |
| const div = document.createElement("div");
| |
| div.className = "day";
| |
| | |
| div.onclick = () => openDay(day);
| |
| | |
| const dayNumber = document.createElement("div");
| |
| dayNumber.className = "day-number";
| |
| dayNumber.textContent = day;
| |
| | |
| div.appendChild(dayNumber);
| |
| | |
| const entries = data[day] || [];
| |
| | |
| entries.forEach(entry=>{
| |
| const e = document.createElement("div");
| |
| e.className = "entry";
| |
| e.textContent = entry.angebot || "(ohne Titel)";
| |
| div.appendChild(e);
| |
| });
| |
| | |
| cal.appendChild(div);
| |
| }
| |
| }
| |
| | |
| function openDay(day){
| |
| | |
| selectedDay = day;
| |
|
| |
|
| document.getElementById("modal").style.display="flex"; | | weekdays.forEach(day => { |
| document.getElementById("modalDate").textContent = | | const el = document.createElement("div"); |
| `Samstag, ${day}. August 2026`.replace("Samstag", new Date(2026,7,day)
| | el.className = "weekday"; |
| .toLocaleDateString("de-DE",{weekday:"long"}));
| | el.textContent = day; |
| | calendar.appendChild(el); |
| | }); |
|
| |
|
| renderEntries();
| | // August 2026 beginnt an einem Samstag |
| }
| | const firstDayOffset = 5; |
|
| |
|
| function closeModal(){
| | // Leere Felder vor dem 1. August |
| document.getElementById("modal").style.display="none"; | | for(let i = 0; i < firstDayOffset; i++){ |
| | const empty = document.createElement("div"); |
| | calendar.appendChild(empty); |
| } | | } |
|
| |
|
| function renderEntries(){
| | // Tage erzeugen |
| | | for(let day = 1; day <= 31; day++) { |
| const container = document.getElementById("entriesContainer");
| |
| container.innerHTML = "";
| |
| | |
| if(!data[selectedDay]){
| |
| data[selectedDay] = [];
| |
| }
| |
| | |
| data[selectedDay].forEach((entry,index)=>{
| |
| | |
| const card = document.createElement("div");
| |
| card.className = "entry-card";
| |
| | |
| card.innerHTML = `
| |
| <label>Angebot</label>
| |
| <input value="${entry.angebot || ''}" onchange="updateField(${index},'angebot',this.value)">
| |
| | |
| <label>Uhrzeit</label>
| |
| <input value="${entry.uhrzeit || ''}" onchange="updateField(${index},'uhrzeit',this.value)">
| |
| | |
| <label>Treffpunkt/Ort</label>
| |
| <input value="${entry.ort || ''}" onchange="updateField(${index},'ort',this.value)">
| |
| | |
| <label>Zielgruppe</label>
| |
| <input value="${entry.zielgruppe || ''}" onchange="updateField(${index},'zielgruppe',this.value)">
| |
| | |
| <label>Anmeldung</label>
| |
| <input value="${entry.anmeldung || ''}" onchange="updateField(${index},'anmeldung',this.value)">
| |
| | |
| <label>Link zum Angebot</label>
| |
| <input value="${entry.link || ''}" onchange="updateField(${index},'link',this.value)">
| |
| | |
| <label>Beschreibung</label>
| |
| <textarea rows="4" onchange="updateField(${index},'beschreibung',this.value)">${entry.beschreibung || ''}</textarea>
| |
| | |
| <div class="actions">
| |
| <button onclick="copyEntryToDate(${index})">
| |
| Auf anderes Datum kopieren
| |
| </button>
| |
| | |
| <button onclick="deleteEntry(${index})">
| |
| Löschen
| |
| </button>
| |
| </div>
| |
| `;
| |
| | |
| container.appendChild(card);
| |
| });
| |
| }
| |
| function copyEntryToDate(index){
| |
| | |
| const targetDay = prompt(
| |
| "Auf welchen Tag im August kopieren? (1-31)"
| |
| );
| |
| | |
| if(!targetDay) return;
| |
| | |
| const day = parseInt(targetDay);
| |
| | |
| if(day < 1 || day > 31){
| |
| alert("Ungültiger Tag.");
| |
| return;
| |
| }
| |
| | |
| if(!data[day]){
| |
| data[day] = [];
| |
| }
| |
|
| |
|
| const copy = JSON.parse( | | const cell = document.createElement("div"); |
| JSON.stringify(data[selectedDay][index])
| | cell.className = "day"; |
| ); | |
|
| |
|
| data[day].push(copy); | | const key = "august2026_" + day; |
| | const savedText = localStorage.getItem(key) || ""; |
|
| |
|
| saveData(); | | cell.innerHTML = ` |
| | <div class="day-number">${day}</div> |
| | <div class="note">${savedText}</div> |
| | `; |
|
| |
|
| alert( | | cell.addEventListener("click", () => { |
| "Termin wurde auf den " | | const current = localStorage.getItem(key) || ""; |
| + day + | | const text = prompt( |
| ". August kopiert."
| | "Eintrag für den " + day + ". August 2026:", |
| );
| | current |
| }
| | ); |
| function addEntry(){
| |
|
| |
|
| data[selectedDay].push({
| | if(text !== null) { |
| angebot:"",
| | localStorage.setItem(key, text); |
| uhrzeit:"",
| | cell.querySelector(".note").textContent = text; |
| ort:"", | | } |
| zielgruppe:"",
| |
| anmeldung:"",
| |
| link:"",
| |
| beschreibung:""
| |
| }); | | }); |
|
| |
|
| saveData(); | | calendar.appendChild(cell); |
| renderEntries();
| |
| }
| |
| | |
| function updateField(index, field, value){
| |
| | |
| data[selectedDay][index][field] = value;
| |
| | |
| saveData();
| |
| }
| |
| | |
| function deleteEntry(index){
| |
| | |
| if(confirm("Eintrag löschen?")){
| |
| | |
| data[selectedDay].splice(index,1);
| |
| | |
| saveData();
| |
| renderEntries();
| |
| }
| |
| }
| |
| | |
| function copyEntry(index){
| |
| | |
| const copy = JSON.parse(
| |
| JSON.stringify(data[selectedDay][index])
| |
| );
| |
| | |
| data[selectedDay].push(copy);
| |
| | |
| saveData();
| |
| renderEntries();
| |
| } | | } |
|
| |
| function exportData(){
| |
|
| |
| const blob = new Blob(
| |
| [JSON.stringify(data,null,2)],
| |
| {type:"application/json"}
| |
| );
| |
|
| |
| const a = document.createElement("a");
| |
| a.href = URL.createObjectURL(blob);
| |
| a.download = "familienangebote_august_2026.json";
| |
| a.click();
| |
| }
| |
|
| |
| function importData(event){
| |
|
| |
| const file = event.target.files[0];
| |
| if(!file) return;
| |
|
| |
| const reader = new FileReader();
| |
|
| |
| reader.onload = e => {
| |
|
| |
| data = JSON.parse(e.target.result);
| |
|
| |
| saveData();
| |
|
| |
| alert("Import erfolgreich.");
| |
| };
| |
|
| |
| reader.readAsText(file);
| |
| }
| |
|
| |
| renderCalendar();
| |
|
| |
| </script> | | </script> |
|
| |
|
| </body> | | </body> |
| </html> | | </html> |