// Wspólne dane formularza między zakładkami (PRE-21). // // Problem: każdą zakładkę (Horoskop / Interpretacje / Kalendarz) wypełniało się // od nowa — te same imię, data, godzina, strefa i miejsce. Teraz raz wpisane // dane wędrują za użytkownikiem. // // Dlaczego localStorage, a nie sesja na serwerze: serwer zostaje BEZSTANOWY // (żadnego magazynu sesji, żadnych danych urodzeniowych trzymanych po stronie // usługi), a przy okazji dane synchronizują się też między osobnymi kartami // przeglądarki — zdarzenie `storage` daje to za darmo. // // UWAGA na kolejność: ten skrypt ładujemy w z `defer`, więc wykonuje się // PO sparsowaniu dokumentu, ale PRZED geo.js (skrypty defer idą w kolejności // dokumentu). Dzięki temu mapa startuje już z odtworzonymi współrzędnymi i nie // trzeba jej potem przestawiać. (function () { 'use strict'; var KEY = 'astrololo.form.v1'; // Pola wspólne dla zakładek. Nazwa pola formularza -> jak je znaleźć. // `geoSearch` (nazwa miejsca) nie ma atrybutu name — szukamy po id. var FIELDS = [ { key: 'person', sel: 'input[name=person]' }, { key: 'date', sel: 'input[name=date]' }, { key: 'time', sel: 'input[name=time]' }, { key: 'tz_offset', sel: 'input[name=tz_offset]' }, { key: 'lat', sel: 'input[name=lat]' }, { key: 'lon', sel: 'input[name=lon]' }, { key: 'house_system', sel: 'select[name=house_system]' }, { key: 'zodiac', sel: 'select[name=zodiac]' }, { key: 'place', sel: '#geoSearch' } ]; function load() { try { return JSON.parse(localStorage.getItem(KEY) || '{}') || {}; } catch (e) { return {}; // uszkodzony wpis nie może zablokować strony } } function save(state) { try { localStorage.setItem(KEY, JSON.stringify(state)); } catch (e) { /* tryb prywatny albo brak miejsca — trudno, formularz ma działać dalej */ } } function apply(state) { FIELDS.forEach(function (f) { var el = document.querySelector(f.sel); if (!el) return; var v = state[f.key]; if (v === undefined || v === null || v === '') return; if (el.value !== v) el.value = v; }); } function collect() { var state = load(); FIELDS.forEach(function (f) { var el = document.querySelector(f.sel); if (!el) return; // pola nieobecnego na tej zakładce nie kasujemy if (el.value === '' || el.value === null) return; state[f.key] = el.value; }); return state; } // 1) odtwórz to, co użytkownik wpisał gdzie indziej apply(load()); // 2) zapisuj każdą zmianę (input dla wpisywania, change dla list i kalendarzy) FIELDS.forEach(function (f) { var el = document.querySelector(f.sel); if (!el) return; ['input', 'change'].forEach(function (ev) { el.addEventListener(ev, function () { save(collect()); }); }); }); // 3) zapisz stan po wysłaniu formularza — po przeładowaniu strony pola mają // pokazywać to, co faktycznie policzyliśmy document.addEventListener('submit', function () { save(collect()); }, true); // 4) druga otwarta karta zmieniła dane -> dociągnij je tutaj na żywo window.addEventListener('storage', function (e) { if (e.key === KEY) apply(load()); }); // 5) geo.js ustawia lat/lon z mapy poza polami formularza — po takiej zmianie // też chcemy zapamiętać (zdarzenie leci z „Tu i teraz" oraz z mapy) document.addEventListener('astrololo:coords', function () { setTimeout(function () { save(collect()); }, 0); }); })();