[addon DateInput] DateInput – html 5 kompatibilní formulářové prvky pro výběr data
- voda
- Člen | 561
DateInput
Formulářový prvek pro výběr data.
- Podporuje všechny typy z HTML5: datum, čas, datum + čas, měsíc, týden
- Pracuje s objekty DateTime
- Není závislý na zobrazeném formátu data (řešeno pomocí druhého hidden inputu)
Ještě zbývá několik nedořešených věcí:
- validace pomocí js
- nejsem si jist, které atributy nechat u viditelného inputu a které u skrytého
Odkaz do doplňků: https://componette.org/search/?…
Připomínky samozřejmě vítány.
- Jan Tvrdík
- Nette guru | 2595
Pokud se nic nezměnilo a mé poslední testy jsou správné, tak
používání validateValid
vede k zacyklení v prohlížeči.
Viditelně se to projevuje především v IE.
- Casper
- Člen | 253
Potvrzuji chybu, bohužel nejsem zběhlý v JS ani
debugování JS, takže nic moc konstruktivního nepřinesu. Použil jsem
nejnovější netteForms.js a dateInput.js z githubu. Chyba se mi
projevuje i ve Firefoxu (při zapnutém FireBugu se zacyklí, bez něj zruší
js validaci všech inputů definovaných až po daném Date s
Form::VALID
)
- Casper
- Člen | 253
Tak jediné co jsem zjistil, tak se to pořád cyklí ve funkcích:
validateControl > validateRule > valid > validateControl >
atd.. ale moc jsem z toho nevykoumal, v čem je problém… výpis
zásobníku, začátek cyklení:
... atd
anonymous()netteForms.js (řádek 167)
anonymous()netteForms.js (řádek 157)
anonymous()netteForms.js (řádek 72)
anonymous()netteForms.js (řádek 167)
anonymous()netteForms.js (řádek 157)
anonymous()netteForms.js (řádek 72)
anonymous()netteForms.js (řádek 105)
anonymous()netteForms.js (řádek 294)
anonymous()netteForms.js (řádek 16)
- voda
- Člen | 561
Ještě k tvému příspěvku z komentářů pod doplňkem
Jen snad: řádek 202 v dateInput.js … atribut id nastavený na null mi dělal ve Firefoxu (5.0) problémy (pod celou stránkou pod skončením html nechával prázdné místo o výšce cca 250px, kliknutím do inputu zmizelo).
Nahradil jsem to za removeAttr, nevím jestli v tom bude nějaký rozdíl, ale uvítal bych, kdybys to mohl otestovat.
- Casper
- Člen | 253
Tak jsem vyzkoušel novou verzi (z githubu, 989e2fa) a narazil jsem na
několik chyb. Snažil jsem se především zprovoznit funkci
Form::RANGE. Ale i jinde budou pravděpodobně chyby, když
jsem zkoušel Form::VALID tak dostávám expcetion (při strictMode na řádku
parent::getControl()
). Form::FILLED jede. Takže ty chyby na co
jsem přišel:
- špatně pojmenované metody (např. validateDateInputRange → validatedateRange)
- $control->value (ve funkci validatedateRange) je NULL
pro TYPE_DATETIME i TYPE_DATETIME_LOCAL (pravděpodobně jde o chybné
formáty, u TYPE_DATETIME_LOCAL jsem nastavil
Y-m-d\TH:i:s\Z
a už to jede, TYPE_DATETIME jsem neopravoval a další formáty nezkoušel. Touto chybou se vždy rozsah data vyhodnotil jako neplatný.
- voda
- Člen | 561
Casper napsal(a):
dostávám expcetion (při strictMode na řádkuparent::getControl()
)
můžeš mi prosím někam nahrát laděnku, podívám se na to.
špatně pojmenované metody (např. validateDateInputRange → validatedateRange)
díky, fixnuto. Měl jsem špatně pojmenované pravidla v
addRule
.
$control->value (ve funkci validatedateRange) je NULL pro TYPE_DATETIME i TYPE_DATETIME_LOCAL (pravděpodobně jde o chybné formáty,…
opravdu se jednalo o špatný formát, datetime
má oproti
datetime-local
navíc časovou zónu, v javascriptu jsme to měl
obráceně.
Díky za hlášení chyb, zkus prosím novou verzi (0bf5df1).
- Casper
- Člen | 253
Nová verze (0bf5df1) se zdá být o něco lepší, Form::VALID
pořád hází exception. TYPE_DATETIME[_LOCAL]
už zdáse
funguje se vším všudy, i JSkově validuje RANGE, ale ostatní typy dokonce
ignorují vložení value do inputu při kliknutí (chyba JS), takže to vůbec
nefunguje.
S tím JS to asi bude vůbec sranda, například pokud dám:
$form->addDate('datum', 'Datum', DateInput::TYPE_DATETIME_LOCAL)
->addRule(Form::RANGE, 'Invalid: %s', array(new \DateTime('now'), NULL));
a zadám datum na „zítra“ s časem menším než nyní a pak zpět kliknu na dnešek, datepicker pořeší nastavení hodnoty na minimální povolený čas (tedy nyní), ale do pomocného inputu se vloží čas, který jsem nastavil pro zítřek. To s pravidlem RANGE od „now“ dá vždy false i když uživatel vidí aktuální čas.
Koneckonců ono RANGE od now je vůbec problémové ne? Když bude mít uživatel nastavený jiný čas než na serveru, může to projít přes JS ale zastaví se to na serveru, takže uživatel nebude chápat, když přece mačkal to tlačítko „nyní“.
Taky bych možná u validace RANGE nastavil ostrou nerovnost (pro vyhození
false), dává větší smysl mít v min
minimální povolenou
hodnotu.
- voda
- Člen | 561
Jak máš zapsáno pravidlo Form::VALID
, nechybí ti tam druhý
parametr $message
?
ostatní typy dokonce ignorují vložení value do inputu při kliknutí (chyba JS)
teď mi to taky nějak nechce fungovat, s každou verzí jquery, … se to může chovat jinak. Zkusím se na to podívat.
zadám datum na „zítra“ s časem menším než nyní a pak zpět kliknu na dnešek, datepicker pořeší nastavení hodnoty na minimální povolený čas (tedy nyní), ale do pomocného inputu se vloží čas, který jsem nastavil pro zítřek
Tohle snad řeší timepicker addon, zkus nejnovější dev verzi
problém s now je akorát ten, že při odeslání je „now“ větší o dobu vyplňování formuláře než „now“ z prvního zobrazení. Datum nastavené u uživatele na tohle vliv mít nebude. Jeho datum se akorát použije na nastavení výchozího data.
- Casper
- Člen | 253
Jak máš zapsáno pravidlo Form::VALID, nechybí ti tam druhý parametr $message
Aha díky, zapomněl jsem, každopádně neměla by být nějaká
implicitní? Vždyť Nette obsahuje nějaké defaultní texty na tyhle pravidla
(třeba setRequired alias Form::FILLED
má „Please complete
mandatory field“), nečekal jsem, že by to mohlo mít vliv.
Tohle snad řeší timepicker addon, zkus nejnovější dev verzi
Žádnou dev verzi jsem (na githubu) nenašel. Je tam stejná verze jako byla naposledy publikována (0.9.7, 10/02/2011). Diff nevykazuje žádné změny od mé verze.
- Casper
- Člen | 253
A našel jsem další poměrně podstatnou chybu. Nastavení rozsahu na platná budoucí data a defaultní hodnoty na minulost způsobí, že při vytvoření inputů je ve skrytém inputu staré datum, ale viditelné datum si datepicker upraví na aktuální, uživatel tedy odešle formulář, protože vše vidí ok, ale dostane chybu o neplatném datu. Příklad:
$form->addDate('datum', 'Datum', DateInput::TYPE_DATETIME_LOCAL)
->setDefaultValue(new \DateTime("- 2 days"))
->addRule(Form::RANGE, 'Datum musí být datum v budoucnu.', array(new \DateTime('now'), NULL));
- jeremy13
- Člen | 18
DateInput jsem vyzkoušel, bohužel nevím, zda je to má chyba, nebo bug,
ale když pak mám formulář ve kterém datum edituji, tak pokud jej nezměním
a nechám tak jak se načte a pouze uložím, tak se uloží nulové datum.
Pak mám ještě problém s tím, že mi funguje pouze DateTime a nikoliv Date,
kalendář se sice zobrazí, ale po kliku na nějaký den zůstane input
prázdný.
- jeremy13
- Člen | 18
Díky za novou verzi, nyní mi jede i typ DATE, ovšem při použití typu
DATETIME mi to sice funguje správně, ovšem když pak otevřu editační
formulář, kdy již je pole vyplněné a formulář pak pouze uložím, tak se
nastaví minimální možné datum, přičemž, když datum před uložením
edituji, tak se uloží správně.
Tak nevím zda někde dělám chybu, případně zda se pole s dateinputem při
načtení defaultní hodnoty nějak nenačte. Za případnou radu dík …
- jeremy13
- Člen | 18
voda napsal(a):
@jeremy13: můžeš to ukázat na konkrétním příkladu, protože buď zkouším něco jiného, nebo je chyba někde jinde.
Tak formulář vytvářím v komponentě a myslím, že nedělám nic zvláštního, konkrétně input datumu přidám následovně:
$form->addDate('start', 'Začátek', DateInput::TYPE_DATETIME);
do šablony pak includuju následující javascript:
$(function() {
$.timepicker.regional['cs'] = {
timeOnlyTitle: 'Vyberte čas',
timeText: 'Čas',
hourText: 'Hodiny',
minuteText: 'Minuty',
secondText: 'Vteřiny',
currentText: 'Nyní',
closeText: 'Zavřít',
timeFormat: 'h:m',
ampm: false
};
$.timepicker.setDefaults($.timepicker.regional['cs']);
$('input[data-dateinput-type]').dateinput({
datetime: {
dateFormat: 'd.m.yy',
timeFormat: 'h:mm'
},
'datetime-local': {
dateFormat: 'd.m.yy',
timeFormat: 'h:mm'
},
date: {
dateFormat: 'd.m.yy'
},
month: {
dateFormat: 'MM yy'
},
week: {
dateFormat: "w. 'týden' yy"
},
time: {
timeFormat: 'h:mm'
}
});
});
DateInput používám aktuální (jak php, tak js).
Jak říkám, když dateinput použiji, tak se vše správně uloží. Když
ovšem načtu editační formulář, kde se dá pole DateInputem upravit, tak
pokud ho neupravím, tak přestože ukazuje správné datum (a i to hidden
pole, které dateinput používá ukazuje správné datum), tak se odešle datum
nulové (0000–00–00 00:00:00).
- Casper
- Člen | 253
Chybu s nulovým datem se mi také nepovedlo dostat / najít.
Každopádně chyba, kterou jsem popisoval v posledním příspěvku přetrvává, zkoušel jsi jí opravit nebo to není tak jednoduché?
Také bych opravdu změnil tu nerovnost u validace RANGE
,
například když dám:
$form->addDate('datum', 'Datum', DateInput::TYPE_DATE)
->addRule(Form::RANGE, 'From today to infinity...', array(new \DateTime('today'), NULL));
…tak mě validační script nepustí, protože chce datum > today (tedy zítřek). A to mi moc smysl nedává, aneb jak už jsem psal: dává mi větší smysl mít v min minimální povolenou hodnotu.
- Casper
- Člen | 253
voda napsal(a):
Nicméně jakej smysl má zadávat výchozí datum mimo povolený rozsah hodnot?
Poměrně velkej, zadáš do formuláře třeba ten dnešek, uloží se ti do db a zítra to budeš chtít upravit, jenže RANGE je dynamický vzhledem k času, takže v db už máš včerejší datum (které už je neplatné), pokud pak použiješ setDeafults s daty z db, máš jako výchozí datum neplatné pro daný rozsah.
Editoval Casper (6. 11. 2011 13:22)
- voda
- Člen | 561
@Casper: Tak jsem se pokoušel to opravit, ale je to
složitější. U type=date
, kde to funguje správně, se pro
vyplnění hidden pole používá altField
a
altFormat
. Timepicker ale používá altField
(pokud
je nastaven) pro zobrazení času, takže u něj používám
onSelect
událost. Ta se ale volá jen když člověk vybere datum
ručně, takže při počátečním načtení se nezavolá.
Jde to ale jednoduše opravit už v PHP, ale dávat to tam nechci, protože podlě mě není správně, aby se automaticky změnilo datum a uživatel si toho nemusí vůbec všimnout. Můžeš si DateInput podědit a přetížit metodu setDefaultValue:
public function setDefaultValue($value) {
if ($this->range['min']) {
$value = max($value, $this->range['min']);
}
$value = max($value, $this->range['max']);
return parent::setDefaultValue($value);
}
- jeremy13
- Člen | 18
voda napsal(a):
Řekl bych, že dělám to samé co ty, ale
0000–00–00 00:00:00
jsme nikdy nedostal. To nulové datum se odešle už z prohlížeče? Nemáš někde živou ukázku?
Tak našel jsem co asi způsobuje problém, ale nevím jak nejlépe to opravit. Když totiž nastavím pomocí DateInputu pole typu datetime, tak se hidden pole nastaví následovně:
<input type="hidden" data-dateinput-type="datetime" name="end" value="2012-01-05T00:00:00Z">
Ovšem pokud se to pole pouze v editačním formuláři načte bez zásahu uživatele, tak se nastaví následovně:
<input type="hidden" data-dateinput-type="datetime" name="end" value="2012-01-05 00:00:00">
Tedy v případě, kdy uživatel pole nezmění, tak tam chybí znaky ‚T‘ a ‚Z‘. Pokud hidden pole manuálně před uložením změním, tak aby tam tyto znaky nechyběly, tak je vše ok.
- mr.mac
- Člen | 87
Je prosím jasné s jakou „nejnovější“ verzí jquery, jquery-ui-timepicker-addon (popř. zda je jiný dateInput.js) to funguje? Nedaří se mi to rozchodit? Žádné chyby to nehlásí – datetimer se při kliknutí do pole neobjeví – vše mám dle návodu. Používám Nette 2.0 beta.
Je potřeba jquery-ui-xxx.custom.js?
Editoval mr.mac (1. 12. 2011 17:24)
- mr.mac
- Člen | 87
Používám: jquery 1.7.1 (min), jquery-ui-timepicker-addon 0.9.7 (0.9.8-dev
jsem nenašel), dateInput.js snad to poslední (v kódu není číslo verze),
jquery-ui-1.8.16.custom.min.
Browsery Chrome 15, Firefox 8, Explorer 9.
Pro jistotu uvádím detaily implementace. Díky za radu.
@layout:
<!DOCTYPE html>
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta http-equiv="Content-Language" content="en" />
<meta name="description" content="Test" />
<meta n:ifset="$robots" name="robots" content="{$robots}">
<link rel="shortcut icon" href="{$basePath}/images/favicon.ico" />
<link rel="stylesheet" media="screen,projection,tv" href="{$basePath}/css/screen.css" type="text/css">
<link rel="stylesheet" media="print" href="{$basePath}/css/print.css" type="text/css">
<link rel="stylesheet" type="text/css" media="screen" href="{$basePath}/css/site.css" />
<script type="text/javascript" src="{$basePath}/js/jquery.min.js"></script>
<script type="text/javascript" src="{$basePath}/js/netteForms.js"></script>
{ifset $is_addon}{include #addon}{/ifset}
</head>
...
Šablona:
{block #addon}
<script type='text/javascript' src="{$basePath}/js/jquery-ui-timepicker-addon.js"></script>
<script type='text/javascript' src="{$basePath}/js/jquery-ui-1.8.16.custom.min.js"></script>
<script type='text/javascript' src="{$basePath}/js/dateInput.js"></script>
<link rel="stylesheet" type="text/css" href="{$basePath}/css/jquery-ui-timepicker-addon.css">
<link rel="stylesheet" type="text/css" href="{$basePath}/css/dateInput.css"></link>
<script type="text/javascript">
$(function() {
$.timepicker.regional['cs'] = {
timeOnlyTitle: 'Vyberte čas',
timeText: 'Čas',
hourText: 'Hodiny',
minuteText: 'Minuty',
secondText: 'Vteřiny',
currentText: 'Nyní',
closeText: 'Zavřít',
timeFormat: 'h:m',
ampm: false
};
$.timepicker.setDefaults($.timepicker.regional['cs']);
$('input[data-dateinput-type]').dateinput({
datetime: {
dateFormat: 'd.m.yy',
timeFormat: 'h:mm'
},
'datetime-local': {
dateFormat: 'd.m.yy',
timeFormat: 'h:mm'
},
date: {
dateFormat: 'd.m.yy'
},
month: {
dateFormat: 'MM yy'
},
week: {
dateFormat: "w. 'týden' yy"
},
time: {
timeFormat: 'h:mm'
}
});
});
</script>
{/block}
...
Bootstrap.php:
...
//DateInput register
Vodacek\Forms\Controls\DateInput::register();
// Run the application!
$application->run();
...
Továrna v prezenteru:
use Nette\Application\UI\Form,
Nette\Application as NA,
Vodacek\Forms\Controls\DateInput;
class NabidkaPresenter extends ObchodPresenter
{
protected function createComponentItemForm()
{
$form = new Form;
$form->addDate('datumod', 'Datum přijetí:', DateInput::TYPE_DATE)
->setRequired('Uveďte datum přijetí.');
$form->addDate('datumdo', 'Požadované datum:', DateInput::TYPE_DATE);
$form->addSubmit('save', 'Uložit')->setAttribute('class', 'default');
$form->addSubmit('cancel', 'Storno')->setValidationScope(NULL);
$form->onSuccess[] = callback($this, 'itemFormSubmitted');
$form->addProtection(self::MESS_PROTECT);
return $form;
}
...
- voda
- Člen | 561
timepicker rozšiřuje datepicker z jqueryUi, takže je potřeba ho načítat až po něm. Pořadí načítání by mělo být:
- jquery
- jqueryUi
- timepicker
- dateInput
dev verzi timepickeru lze získat na githubu v dev větvi.
- Kaspis
- Člen | 13
Ahoj, rád bych použil tento doplněk, bohužel se mi to nedaří rozchodit. Firebug píše chybu v JS „Nette is not defined“ na řádku „Nette.validators …“
Používám nejnovější Nette 2.0.1, jquery.nette.js a ajax.forms.js a tyto verze
- jquery 1.7.1
- jquery ui 1.8.18
- timepicker 0.9.9
Skripty jsou načítány ve správném pořadí.
Někdo podobný problém? Díky
- voda
- Člen | 561
Zjistil jsem, že není netteForms.js jako netteForms.js. V downloadu je ten druhý (z nette/nette) pro který je i psaný js z DateInputu a zdá se, že je i aktuálnější. Takže bych doporučil použít ten a mělo by to fungovat.
- pata.kusik111
- Člen | 78
Na gitHub jQuery-Timepicker-Addon je request na doplnění české lokalizace pro tento addon. Jinak do té doby můžete nalést českou lokalizaci (snad kompletní) na mém githubu.
- pata.kusik111
- Člen | 78
Při stisku tlačítka nyní nefunguje změna času ale pouze data. Zůstane buď předchozí hodnota(pokud nějaké byla), nebo se nastaví 00:00:00. Nefunguje to ani v ukázce, která je na stránce addonu.