Uživatelská příručka
Návod, jak Gregory nasadit do reálného projektu. Čte se odshora dolů, ale klidně skoč rovnou do kuchařky — recepty jsou celé a fungují samostatně. Kompletní výčet všeho, co se dá nastavit, je v API dokumentaci.
Je to komponenta pro výběr data, rozsahu dat, času a období. Pracuje výhradně v místním čase prohlížeče a časové zóny neřeší — datum, na které uživatel klikne, je to datum, které dostaneš. Není to knihovna na počítání s daty; na to si vezmi cokoli jiného, Gregory ti do toho mluvit nebude.
Instalace
Se sestavovacím nástrojem (Vite, Webpack, Rollup). Instaluje se rovnou
z GitHubu — do npm registru se knihovna vydávat nebude. npm
si ji po naklonování sestaví sám, nic se nemusí buildit ručně:
npm install github:svatekr70/gregory # poslední main npm install github:svatekr70/gregory#v0.3.0 # konkrétní verze
import { Gregory } from '@svatekr70/gregory' import '@svatekr70/gregory/style.css'
Jméno balíčku je @svatekr70/gregory i při instalaci
z GitHubu, takže importy vypadají obvykle.
Bez buildu, přímo do stránky — sestavená knihovna se publikuje spolu
s touhle dokumentací, takže jde načíst z URL. UMD podoba vystaví
globální Gregory:
<link rel="stylesheet" href="https://svatekr70.github.io/gregory/dist/gregory.css"> <script src="https://svatekr70.github.io/gregory/dist/gregory.umd.js"></script> <script> new Gregory.Gregory('#termin', { mode: 'date', locale: 'cs' }) </script>
Nebo jako ES modul, bez globální proměnné:
<script type="module"> import { Gregory } from 'https://svatekr70.github.io/gregory/dist/gregory.js' new Gregory('#termin', { mode: 'date', locale: 'cs' }) </script>
Adresy výše ukazují na poslední verzi na main a visí na
cizím serveru. Pro ostrý provoz si stáhni přílohu vydání
z GitHub
Releases a soubory si nahraj k sobě.
Styly se importují jednou za aplikaci, ne u každého pickeru. Motivy jsou v samostatném souboru a jsou nepovinné:
import '@svatekr70/gregory/themes.css'
První picker
Gregory se věší na existující prvek. Nejčastěji na textový input:
<input type="text" id="termin" placeholder="Vyber datum…">
const picker = new Gregory('#termin', { mode: 'date', locale: 'cs', })
To je všechno. Klik do pole otevře kalendář, klik na den ho zavře a do pole napíše datum. Hodnotu si vyzvedneš kdykoli:
picker.getValue() // Date, nebo null
<input type="date">
Nativní pole vypadá v každém prohlížeči jinak, neumí rozsah ani presety a jeho vyskakovací kalendář se nedá stylovat. Gregory je naopak všude stejný a řídí se tvým designem. Když ti nativní pole stačí, používej ho — tahle knihovna začíná dávat smysl u rozsahů, omezení a vlastního vzhledu.
Který režim zvolit
Volba mode je první a nejdůležitější rozhodnutí: určuje
tvar hodnoty i výchozí chování zbytku.
| Potřebuji… | mode | Dostanu |
|---|---|---|
| jeden den (narozeniny, splatnost) | 'date' | Date | null |
| období od–do (pobyt, filtr) | 'range' | { from, to } |
| den i hodinu (schůzka) | 'datetime' | Date | null |
| od kdy do kdy včetně času (směna) | 'datetime-range' | { from, to } |
| několik samostatných dnů (dovolená po dnech) | 'multiple' | Date[] |
| celý měsíc (uzávěrka) | 'month' | Date = 1. den měsíce |
| čtvrtletí (report) | 'quarter' | Date = 1. den čtvrtletí |
| rok (ročenka) | 'year' | Date = 1. leden |
Režim se dá měnit i za běhu, ale je to spíš pro konfigurátory než pro běžné stránky:
picker.setOptions({ mode: 'range' })
Hodnota se přitom nezahazuje, jen se čte podle nového tvaru: z rozsahu
zůstane po přepnutí na date jeho začátek a v režimu
multiple se neprojeví vůbec, protože seznam dnů je prázdný.
Po návratu zpátky na range je celý rozsah zase na místě.
Když má hodnota při přepnutí opravdu zmizet, zavolej
clear().
Období vs. rozsah
Na „celý srpen" jsou dvě cesty. mode: 'month' vrátí jeden
Date (1. 8.) a je to volba filtru — server si sám dopočítá,
že jde o celý měsíc. mode: 'range' s presetem „Tento měsíc"
vrátí { from: 1. 8., to: 31. 8. } a je to skutečný rozsah,
který uživatel může ještě upravit. Ptej se, jestli má jít hranice měnit:
když ne, stačí období.
Čtení a nastavení hodnoty
Picker rozlišuje dva stavy: potvrzenou hodnotu a rozpracovaný výběr. Uživatel s otevřeným panelem klikl na první konec rozsahu — výběr se změnil, hodnota ještě ne.
picker.getValue() // potvrzené: to, co je v poli picker.getSelection() // rozpracované: i poloviční rozsah
Na změny se dá poslouchat. Pro ukládání chceš skoro vždycky
apply, ne change:
picker.on('apply', ({ value }) => ulozit(value)) picker.on('change', ({ value, complete }) => { // Padá při každém kliknutí. complete je false, dokud rozsah nemá oba konce. })
Nastavit hodnotu můžeš čímkoli, co jde přečíst jako datum — ISO řetězec,
Date, timestamp:
picker.setValue('2026-08-13') picker.setValue({ from: '2026-08-10', to: '2026-08-16' }) picker.setValue(['2026-08-10', '2026-08-16']) picker.clear()
new Date('2026-08-13')
JavaScript takový řetězec čte jako půlnoc v UTC, takže
v Praze z něj v srpnu vyjde 13. srpna 02:00 (v zimě 01:00) a v New Yorku
12. srpna 20:00. Gregory si ISO řetězce parsuje sám a v místním čase, takže
setValue('2026-08-13') je vždycky 13. srpna. Když si datum
skládáš ručně, použij new Date(2026, 7, 13) nebo utilitu
createDate(2026, 7, 13).
Text v poli a hodnota pro server
Do pole se píše datum pro lidi — 13. 8. 2026, podle jazyka.
Server to spolehlivě nepřečte, tak mu posílej ISO tvar:
import { formatISODate } from '@svatekr70/gregory' const den = picker.getValue() // v režimu date: Date | null if (den) odeslat(formatISODate(den)) // '2026-08-13'
V TypeScriptu getValue() vrací sjednocení všech tvarů
(Date | DateRange | Date[] | null), protože jeden picker umí
všechny režimy. Když víš, který máš, zúž si typ —
picker.getValue() as Date.
U formulářů to za tebe udělá submitName — viz dál.
Odeslání formuláře
Nejjednodušší cesta: nech Gregory vyrobit skryté pole s ISO hodnotou. Vznikne hned vedle viditelného vstupu, takže spadne do stejného formuláře.
new Gregory('#termin', { mode: 'date', submitName: 'termin', }) // odejde termin=2026-08-13
U rozsahu vzniknou pole dvě, s příponami _from a
_to. Vlastní jména se dají zadat dvojicí:
new Gregory('#pobyt', { mode: 'range', submitName: { from: 'prijezd', to: 'odjezd' }, })
Validace
Picker sám nepustí do hodnoty nic, co odporuje nastaveným mezím — ani
přes setValue(), ani rukou napsaným textem. Odmítnutí ohlásí
událostí invalid, takže si formulář může říct své:
picker.on('invalid', ({ reason }) => { chyba.textContent = reason === 'unreadable' ? 'Datum se nepodařilo přečíst.' : 'Tenhle termín nejde vybrat.' })
Odmítnuté pole zároveň dostane aria-invalid="true", což se
dá obarvit jedním pravidlem:
input[aria-invalid] { border-color: #d64545; }
Povinné pole
Vestavěné required na viditelném poli funguje: dokud je
prázdné, prohlížeč formulář neodešle. Se skrytým polem
z submitName ale required nesahá — na to si
napiš kontrolu při odeslání:
form.addEventListener('submit', (e) => { if (!picker.getValue()) { e.preventDefault(); chyba.textContent = 'Vyber termín.' } })
Omezení výběru
Omezení se skládají — platí všechna najednou a zakázaný den je zakázaný i pro klávesnici.
| Chci… | Volba |
|---|---|
| jen budoucnost | min: today() |
| nejvýš rok dopředu | max: addDays(today(), 365) |
| bez víkendů a svátků | isDisabled: (d) => … |
| pobyt nejvýš na 14 nocí | maxSpan: 15 |
| pobyt aspoň na dvě noci | minSpan: 3 |
| rozsah nesmí přeskočit obsazený den | stopAtDisabled: true |
| jen v otevírací době | minTime, maxTime, timeWindow |
nejvýš pět dnů v multiple | maxSelected: 5 |
Rozsah 10.–12. srpna jsou tři dny, ale jen dvě noci.
Pro ubytování na nejvýš 14 nocí je tedy správně maxSpan: 15.
Stejné pravidlo platí pro minSpan i pro počet dnů
v informačním řádku.
Zakázané dny
isDisabled dostane Date nastavené na půlnoc
daného dne a vrací true pro dny, které nejdou vybrat.
Volá se pro každou vykreslenou buňku, takže ať je rychlá — hledání
v Setu ano, dotaz na server ne:
let obsazeno = new Set(['2026-08-15', '2026-08-16']) const picker = new Gregory('#pobyt', { mode: 'range', isDisabled: (d) => obsazeno.has(formatISODate(d)), })
Když se seznam obsazených dnů dotáhne později, funkce si nová data vezme sama — jen jí musíš dát vědět, ať se panel překreslí:
obsazeno = new Set(await nactiObsazene()) picker.setOptions({}) // překreslí panel s aktuálními daty
Porovnání období
Filtr v přehledu skoro nikdy nekončí u jednoho období — hned za ním
přijde otázka „a jak to bylo předtím?“. compare to období
dopočítá samo. Nevybírá se; v kalendáři se jen vyznačí pruhem pod dny
a přijde s hodnotou:
const filtr = new Gregory('#obdobi', { mode: 'range', locale: 'cs', summary: true, compare: 'previous', }) filtr.on('apply', ({ value, compare }) => { nacistData(value.from, value.to) if (compare) nacistPorovnani(compare.from, compare.to) })
Na výběr jsou tři způsoby, jak období odvodit, plus vlastní funkce:
'previous'— stejně dlouhý úsek těsně před začátkem. To je to, co člověk myslí „minulým obdobím“.'year'— stejná data o rok zpět. Sedí datum, ne dny v týdnu.'year-weekday'— posun o 364 dní. Sedí dny v týdnu, ne datum. Pro týdenní a prodejní reporty je tohle obvykle to správné: víkend se porovnává s víkendem.
Kdyby se počítalo jen po dnech, vyšlo by „předchozí období“ k celému únoru na 4.–31. ledna — únor je o tři dny kratší. Výběr, který přesně odpovídá kalendářnímu měsíci, čtvrtletí nebo roku, se proto porovnává s celým předchozím celkem.
Když má porovnání vycházet z něčeho vlastního — z fiskálního roku,
z minulé sezóny, z období uloženého v nastavení — dej místo názvu
funkci. Dostane vybraný rozsah setříděný a vrací dvojici dat, nebo
null, když se pro ten výběr porovnávat nemá:
compare: ({ from, to }) => [
minulaSezona(from),
minulaSezona(to),
]
Období se dá dopočítat i bez pickeru — stejnou funkcí, jakou používá knihovna uvnitř. To se hodí, když stejný výpočet potřebuje i dotaz na serveru:
import { comparePeriod } from '@svatekr70/gregory' comparePeriod({ from, to }, 'year-weekday')
Aktuální období vrací i filtr.getCompare().
Bez volby compare je to vždycky null —
porovnávání je ve výchozím stavu vypnuté.
Kam picker pověsit
Na jeden input
Výchozí případ. Rozsah se do jednoho pole zapíše jako
10.–16. 8. 2026.
Na dvě pole
Když má formulář zvlášť „od" a zvlášť „do", drží je jeden picker pohromadě — panel otevře kterékoli z nich a výběr se rozdělí do obou:
new Gregory('#od', { mode: 'range', endInput: '#do', })
Na cokoli jiného
Datum bývá i mimo formulář — v odznaku, v buňce tabulky. Picker umí
viset na jakémkoli prvku: klik ho otevře, potvrzená hodnota se vypíše
dovnitř. Když má prvek potomka s data-gr-value, píše se text
do něj, takže ikona vedle zůstane:
<span class="badge" id="splatnost" data-value="2026-08-13"> 📅 <span data-gr-value>13. 8. 2026</span> </span>
const picker = new Gregory('#splatnost', { mode: 'date' }) splatnost.addEventListener('gregory:change', (e) => ulozit(e.detail.value))
Natrvalo rozbalený
inline: true vykreslí panel na místo cílového prvku místo
popoveru. Hodí se do postranních filtrů; s summary: true
má i řádek, který slovy říká, co je vybrané.
Deklarativně, v HTML
Custom element se nastavuje atributy; JavaScript je potřeba jen jednou, na jeho registraci:
<gregory-picker mode="range" locale="cs" months="2"></gregory-picker>
import { defineElement } from '@svatekr70/gregory' defineElement()
Jazyk a formáty
Bez nastavení si Gregory vezme jazyk prohlížeče. Explicitně stačí BCP 47 tag:
new Gregory('#termin', { locale: 'cs' })
Názvy měsíců, dnů, formát data i skloňování počtu dnů řeší
Intl, takže fungují pro jakýkoli jazyk.
Vlastní překlad mají popisky tlačítek — hotové jsou pro češtinu,
slovenštinu, angličtinu, němčinu, polštinu, španělštinu, francouzštinu
a italštinu. Ostatní jazyky dostanou anglické popisky, dokud jim nějaké
nedodáš:
import { registerTranslation } from '@svatekr70/gregory' registerTranslation('nl', { labels: { apply: 'Toepassen', … }, presets: { … }, days: { … } })
Přejmenovat jedno tlačítko jde i bez překladu — locale
bere i objekt, který se přiloží na vyřešený jazyk:
new Gregory('#termin', { locale: { code: 'cs', labels: { apply: 'Rezervovat' } }, })
Text v poli si můžeš napsat úplně sám:
new Gregory('#termin', { format: (value) => value ? `termín ${formatISODate(value)}` : '', })
Vzhled
Panel nemá stínový DOM, takže se dá stylovat běžným CSS. Skoro všechno ale jde přenastavit proměnnými, což je odolnější než přepisovat jednotlivá pravidla:
.gr {
--gr-accent: #0e7c86;
--gr-radius-day: 999px;
--gr-day-size: 26px;
}
Šířku panelu určuje velikost políčka dne, ne dostupné místo. Hustotu
tedy měň přes --gr-day-size, --gr-gap
a --gr-pad, ne pevnou šířkou.
Den je ve výchozím stavu čtverec, protože --gr-day-height
vychází z --gr-day-size. Když se pod čísla vykreslují
značky (vytížené dny), zvedni
jen výšku — sloupce se řídí pořád šířkou, takže panel
nenaroste do stran:
.gr {
--gr-day-height: 38px;
--gr-day-badge-size: 11px;
}
Panel popoveru žije na <body>, takže se k němu
selektorem přes rodiče nedostaneš. Vlastní třídu mu dá
className — tudy se nasazují i hotové motivy:
new Gregory('#termin', { className: 'gr-theme-clinic gr-density-compact' })
Motivy (blueprint, riso, clinic,
nocturne) a stupně hustoty jsou v themes.css.
Všechny jsou jen sadou proměnných, takže si vlastní motiv uděláš
zkopírováním kteréhokoli z nich.
Výchozí motiv reaguje na prefers-color-scheme sám. Když
má aplikace vlastní přepínač, přenastav proměnné pod svou třídou:
.dark .gr { --gr-bg: #12141a; --gr-fg: #e8eaed; … }
Klávesnice
Panel je ovladatelný bez myši a to je součástí veřejného chování — nemusíš nic zapínat.
| Klávesa | Co udělá |
|---|---|
↓ v poli | otevře panel a skočí do mřížky |
| šipky | posun po dnech a týdnech |
PageUp / PageDown | o měsíc zpět a vpřed |
Enter | vybere den; v poli přečte napsané datum a zavře |
Esc | zahodí rozpracovaný výběr, zavře panel a vrátí fokus do pole |
Datum se dá i prostě napsat: 13. 8. 2026, 13.8.
(doplní se letošní rok) i 2026-08-13. Nesrozumitelný text se
vrátí na poslední platnou hodnotu. Když psaní nechceš, vypni ho přes
allowTyping: false. Samotné readonly na poli
pickeru nevadí — otevře se a datum do pole zapíše. Zamknout ho i tam jde
volbou lockOnReadonly: true.
Recept: rezervace ubytování
Příjezd a odjezd, obsazené termíny, nejméně dvě noci a nejvýš čtrnáct, rozsah nesmí přeskočit obsazený den:
import { Gregory, formatISODate, today } from '@svatekr70/gregory' const obsazeno = new Set(await nactiObsazene()) const picker = new Gregory('#prijezd', { mode: 'range', locale: 'cs', endInput: '#odjezd', min: today(), minSpan: 3, // dvě noci maxSpan: 15, // čtrnáct nocí isDisabled: (d) => obsazeno.has(formatISODate(d)), stopAtDisabled: true, submitName: { from: 'prijezd', to: 'odjezd' }, summary: true, })
Po prvním kliknutí se zašedí všechno, co by rozsah protáhlo přes obsazený den nebo mimo povolenou délku — uživatel tedy nemá jak vybrat termín, který mu stejně zamítneš.
Recept: filtr v přehledu
Rozbalený panel v postranním sloupci, zkratky typu „Posledních 30 dní" a okamžité potvrzení bez tlačítek:
const filtr = new Gregory('#filtr', { mode: 'range', locale: 'cs', inline: true, autoApply: true, summary: true, presets: true, months: 1, }) filtr.on('apply', ({ value }) => nacistData(value))
Vlastní zkratky nahradí vestavěné. Rozsah se vyhodnocuje až při kliknutí, takže „dnes" zůstane dnešek i po půlnoci:
presets: [
{ label: 'Toto čtvrtletí', range: () => [zacatekCtvrtleti(), today()] },
{ label: 'Loni', range: () => ['2025-01-01', '2025-12-31'] },
]
Když má filtr vracet celé období a ne konkrétní hranice, sáhni rovnou po
mode: 'month' nebo 'quarter'. A když se má
vybrané období s něčím srovnávat, přidej compare —
viz Porovnání období.
Recept: objednání na hodinu
Termín i čas, po půlhodinách, v otevírací době — a ta je v sobotu jiná než ve všední den:
new Gregory('#objednani', { mode: 'datetime', locale: 'cs', min: today(), timeStep: 30, minTime: '08:00', maxTime: '18:00', // V sobotu jen dopoledne, v neděli zavřeno. timeWindow: (d) => d.getDay() === 6 ? { min: '09:00', max: '12:00' } : null, isDisabled: (d) => d.getDay() === 0, submitName: 'objednani', })
Vybraný čas, který by se přesunem na jiný den dostal mimo okno, se srovná dovnitř — z pátečních 17:00 tak v sobotu vyjde 12:00, ne nabídka, kterou nemůžeš splnit.
V patičce je místo Dnes odkaz Nyní: nastaví
dnešek i aktuální čas, srovnaný po timeStep do stejného
okna. Popisek se dá přejmenovat přes labels.now.
Recept: vytížené dny
Kalendář, ve kterém je pod každým dnem vidět, kolik už je na něj
naplánováno — typicky u plánování kontaktů, směn nebo návštěv. Počty
vrací dayBadge, barvu podle vytížení nasadí
dayClass:
const hovory = new Map([['2026-08-27', 3], ['2026-08-28', 12]]) const pocet = (d) => hovory.get(formatISODate(d)) ?? 0 new Gregory('#plan', { mode: 'date', locale: 'cs', dayBadge: (d) => String(pocet(d)), dayClass: (d) => pocet(d) > 8 ? 'je-plno' : pocet(d) > 3 ? 'je-rusno' : null, className: 'plan-kontaktu', })
.plan-kontaktu {
/* Vyšší buňka, ale stejně široký kalendář. */
--gr-day-height: 38px;
--gr-day-badge-size: 11px;
--gr-day-badge-gap: 3px;
}
.gr-day.je-rusno .gr-day-badge { color: #b45309; }
.gr-day.je-plno .gr-day-badge { color: #b91c1c; }
Řádek pro značku si drží každý den, i ten, kterému
dayBadge vrátí null — čísla dnů tak zůstanou
na jedné lince a řádek se nerozklíží. Prázdný řetězec místo počtu
vykreslí jen tečku, na „tady něco je" bez čísla.
Značka nereaguje na myš, takže den zůstává klikatelný celý. Pro dny
přesahující ze sousedních měsíců se dayBadge volá stejně
jako dayClass — obchodník plánující přes přelom měsíce tak
vidí, že prvního je už nabito. Když o cizí měsíc nestojíš, vrať pro něj
null:
dayBadge: (d) => d.getMonth() === mesic ? String(pocet(d)) : null
Recept: migrace ze starého pickeru
Z <input type="date">
Změň typ na text — nativní kalendář by se otevíral přes ten
náš — a hodnotu čti z pickeru, ne z pole:
// bylo <input type="date" name="termin"> // je <input type="text" id="termin"> new Gregory('#termin', { mode: 'date', locale: 'cs', submitName: 'termin' })
Skryté pole ze submitName posílá stejný ISO tvar, jaký
posílalo nativní pole, takže server se měnit nemusí.
Z jQuery daterangepicker
| daterangepicker | Gregory |
|---|---|
startDate, endDate | value: { from, to } |
minDate, maxDate | min, max |
dateLimit | maxSpan |
singleDatePicker | mode: 'date' |
timePicker | mode: 'datetime' / 'datetime-range' |
timePickerIncrement | timeStep |
ranges | presets |
autoApply | autoApply |
locale.format | řeší locale, jinak format |
on('apply.daterangepicker') | picker.on('apply', …) |
Největší rozdíl: Gregory nevrací momenty ani řetězce, ale
Date. A nepotřebuje jQuery ani moment.js, takže s ním
z projektu často zmizí dvě další závislosti.
Recept: React, Vue, Svelte
Gregory je obyčejná třída, takže do komponenty patří tam, kde vzniká DOM,
a v úklidu se musí zavolat destroy(). V Reactu:
function DateField({ value, onChange }) { const ref = useRef(null) const picker = useRef(null) useEffect(() => { picker.current = new Gregory(ref.current, { mode: 'date', locale: 'cs' }) picker.current.on('apply', (e) => onChange(e.value)) return () => picker.current.destroy() }, []) // Hodnota shora dovnitř, bez události zpátky — jinak vznikne smyčka. useEffect(() => picker.current?.setValue(value, { silent: true }), [value]) return <input ref={ref} type="text" /> }
Dvě věci, na kterých to obvykle padá: efekt s prázdným polem závislostí
(jinak se picker přestavuje při každém renderu) a
{ silent: true } při zápisu hodnoty shora. Ve Vue je to
onMounted / onBeforeUnmount, ve Svelte
onMount s návratovou funkcí — princip je stejný.
Balíček definuje custom element, takže samotný import potřebuje DOM —
v Node spadne na HTMLElement is not defined. V Next.js,
Nuxtu a spol. si ho proto natáhni až v prohlížeči: dynamickým importem
uvnitř efektu, nebo komponentou vyloučenou ze serverového renderu
(next/dynamic s ssr: false).
Řešení potíží
Panel se neotevře
Pole je disabled, nebo má picker disabled: true
či lockOnReadonly: true nad readonly polem. Když
chceš zabránit jen psaní, použij allowTyping: false.
Panel vypadá rozsypaně
Nejspíš chybí gregory.css. Druhá možnost: stránka má
globální pravidlo na značky, ze kterých je panel poskládaný. Gregory se
proti tomu brání resetem s nulovou specificitou, ale
section { padding: 52px 0 !important } ani ten reset
nepřebije.
Poslední sloupec dnů není vidět
Panel je v užším místě, než je jeden měsíc. Neořízne se — dá se
odrolovat do strany — ale lepší je dát mu místo: zmenši
--gr-day-size, sniž months na 1 nebo vypni
presets.
Značky pod dny se do políčka nevejdou
Výchozí den je čtverec 24 × 24 px a číslo se značkou se do něj vejde
jen tak tak. Zvedni --gr-day-height — šířku sloupců drží
--gr-day-size, takže se kalendář nerozšíří. Písmo značky
má vlastní proměnnou --gr-day-badge-size.
Datum se posunulo o den
Skoro jistě někde v kódu je new Date('2026-08-13'), což je
půlnoc v UTC. Používej createDate(), nebo ISO řetězec
předej rovnou pickeru, který ho čte v místním čase.
Hodnota v poli je jiná než v databázi
V poli je datum pro lidi, podle jazyka. Pro server ber
picker.getValue() a formatISODate(), nebo nech
pracovat submitName.
change se ozývá pořád dokola
change padá při každém kliknutí, i uprostřed rozsahu. Na
ukládání je apply. A hodnotu nastavovanou zvenčí posílej
se { silent: true }, jinak si posluchače vyvoláš sám.
Picker zůstal viset po přepnutí stránky
Panel popoveru žije na <body>, takže odstranění pole
ho samo neuklidí. V SPA vždycky volej picker.destroy().
Kam dál
Demo má konfigurátor, ve kterém si každou volbu naklikáš a rovnou vidíš kód. API dokumentace je úplný výčet voleb, metod, událostí, CSS proměnných a typů. Repozitář bere hlášení chyb i nápady.