site logo

Webový formulář pro zadávaní datumu a času

Zadávání datumu a času ve formuláři a validace těchto údajů není triviální záležitostí. Standard HTML5 sice zavádí pro tento účel nové formulářové prvky, ale ne všechny browsery tyto formulářové prvky zvládají. Jak zadat datum a čas do formuláře pomocí myši způsobem drag&drop, který pracuje i ve starších browserech podle standardu HTML4 je posán v tomto článku.

Serverem předvyplněné, správně formátované vstupní pole např. aktuálním datumem značně ulehčí práci. Je mnohem jednodušší správně formátované datum upravit, než nový zápis do prázdného pole formuláře. Jednoduchá je také volba datumu pomocí řady select prvků, vždy samostatný pro den, měsíc, rok. Další způsob je nabídnout kalendář a výběr provést kliknutím na požadované datum. V ukázce aplikace měření rozměrů jsou použity oba způsoby zadávání datumu. "Blízké" datum vybereme kliknutím na kalendář, "vzdálené" datum vybereme pomocí select prvků.

Někdy postačí určit čas pouze s přesností na celé hodiny. Např. v aplikaci protokoly kvality vedle vstupního pole pro datum a čas jsou dvě tlačítka pro krokování času (následně i datumu) o jednu hodinu. Správný formát zajisťuje server pomocí Ajaxu, a tedy hodnota nemusí být testována ve validačním skriptu. Vstupní pole má atribut readonly, což znamená že hodnota může být přepsána pouze skriptem, nikoli uživatelem.

Výběr dat z databáze podle datumu je bezpečná operace a JavaScript ani nemusí kontrolovat správnost zadaného datumu, při chybě server totiž může doplnit nejbližší vhodné datum. Pokud formulář vyvolá zápis do databáze musíme testovat zadané datum vždy.

 

Následující ukázka je část formuláře z aplikace pro plánování jízd taxi. Datum zvolíte kliknutím na kalendář, čas vyberete myší pomocí drag&drop na časové stupnici. Datum a čas můžete zadat i klávesnicí a po kliknutí mimo vstupní pole (onblur) se provede validace zadané hodnoty a upraví se grafické zobrazení.

16.10.2017 - 5.11.2017
16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 1 2 3 4 5
datum a čas

Při popisu kódu se soustředím jen na funkce pořebné pro drag&drop. Metody validace hodnoty datum a čas zadané z klávesnice jsou popsány v článku formulář a skripty, zde jsou použity mírně upravené funkce. V případě potřeby si prohlédněte zdrojový kód stránky. Server připraví kalendář tak, aby zobrazil aktuální týden plus dva týdny následující, aktuální čas je zaokrouhlený na 5 minut.


<style type="text/css">
...
#ruler {position: relative; top: 0; left: 0; height: 30px; width: 580px;
        margin: 4px 0 0 0;}
#scale {height: 30px; width: 580px; border: 0; margin: 0;}
#arrow {position: absolute; top: 13px; left: -4px; height: 18px; width: 13px;
        border: 0; z-index: 2;}
</style>

<body onload="keybInput();">
...
<div id="ruler">
<img id="scale" src="scale.png" onmousedown="return false;" alt="">
<img id="arrow" src="arrow.gif" onmousedown="return dragStart(event);" alt="">
</div>
...
<input type="text" class="iC" name="dateTime" id="dateTime"
 value="<%= dateTime %>" onblur ="keybInput()">
...
</div>
...

Obrázky stupnice a šipka jsou uzavřeny do konteineru #ruler  (pravítko), který má CSS pozici relative. Uvnitř konteineru pak můžeme použít pozicování absolute. To totiž potřebujeme pro správnou funkci drag&drop. První obrázek #scale  (stupnice) pomáhá orientaci, druhý obrázek #arrow  (šipka) je obrázek který budeme táhnout myší drag&drop, proto musí mít pozici absolute. Jeho CSS vlastnost left  pak určuje vzdálenost vůči levé straně konteineru a ta je použita pro výpočet času.

Dále je navázáno několik java skriptových událostí (zobrazených červeně). Po načtení stránky je provedena funkce keybInput(), ta zajistí správné zobrazení vybraného dne v kalendáři a umístění šipky označující čas. Proto musí formulářové vstupní pole dateTime obsahovat platné datum a čas již při načtení stránky. Toto zajistí server při generování kódu.

Událost onmousedown="return dragStart(event);"  v elementu arrow  zahájuje drag&drop tohoto obrázku. Důležitý je příkaz return, který předává správnou hodnotu do systému řízení událostí. Bez příkazu return nefunguje drag & drop ve Firefoxu, který má poněkud odlišný způsob probublávání událostí.

Firefox (v.2.0.0.7) nezachytí událost onmouseup pokud vyjedete myší ven z okna browseru a tam uvolníte tlačítko myši. Po návratu myši do okna prohlížeče funkce drag&drop zůstane aktivní i při uvolněném tlačítku myši. Takto se chovají i jiné ukázky na internetu. Od verze FireFox 3 je všechno v pořádku.

V Opeře (nižší verze než v.9.25) pokud není přilinkovaná funkce onmousedown="return false;" v elementu scale, je možné táhnout myší průhlednou kopii obrázku scale po celé ploše okna, po uvolnění tlačítka myši kopie zmizí. Opera také vykazuje něco jako mrtvý chod. Než se šipka při tažení začne pohybovat, musíme provést krátký "prázdný" pohyb.


<script type="text/javascript">
var Xstart, dragOn=false;

function dragStart(event) {
  event = event || window.event;
  Xstart = parseInt(document.getElementById("arrow").offsetLeft)-event.clientX;
  dragOn = true;
  return false;
}
function mouseMove(event) {
  if (dragOn==true) {
    event = event || window.event;
    Xmove = Xstart + event.clientX;
    Xmove = Xmove < -4 ? -4 : Xmove;
    Xmove = Xmove > 571 ? 571 : Xmove;
    document.getElementById("arrow").style.left = Xmove + "px";
    showTime();
    return false;
  }
}
function mouseUp() {
  dragOn = false;
}
function showTime() {
  dt = parseInt((parseInt(document.getElementById("arrow").style.left)+4)/2);
  hours = parseInt(dt/12);
  minutes = 5*(dt - 12*hours);
  if(hours < 10) hours = "0" + hours;
  if(minutes < 10) minutes = "0" + minutes;
  document.getElementById("dateTime").value = dtArray[0] +
 " " + hours + ":" + minutes;
}
document.onmousemove=mouseMove;
document.onmouseup=mouseUp;
</script>

Ukázka javaskriptového kódu zajišťuje tažení šipky, zobrazení času a přilinkování dalších událostí od aktivit myši. Globální proměnná Xstart uchovává x-ovou souřadnici pozice myši kde došlo k nastartování tažení, proměnná dragOn určuje mód tažení.

function dragStart(event)
Funkce je volána při stisknutí tlačítka myši nad obrázkem šipky. Nejdříve se sjednotí zdroj události, který se liší v různých prohlížečích. Dále je vypočtena souřadnice x kde došlo ke zmáčnutí tlačítka, a pak je nastaven mód aktivního tažení.

function mouseMove(event)
Událost onMouseMove je přilinkovaná k celému dokumentu na konci ukázky skriptu. Funkce je tedy volána při každém pohybu myši po ploše naší stránky. Výkonné instrukce jsou provedeny jen když je aktivní mód tažení, tedy když je nastavena hodnota proměnné dragOn na true.

Opět se najde zdroj události, vypočte se nová souřadnice časového kurzoru a provede se test na limity, tak aby kurzor nepřekročil stupnici. Dále je kurzor posunut na novou souřadnici (nutno přidat jednotky pixely) a zavolá funkci pro zobrazení nového časového údaje.

function mouseUp()
Ukončí mód drag & drop nastavením proměnné dragOn na hodnotu false. Funkce mouseMove() i nadále příjmá zprávy od pohybu myši, ale již neprovádí vyhodnocení.

function showTime()
Vypočte a zobrazí digitální hodnotu času podle aktuální pozice šipky. Pozici left šipky musíme korigovat na posunutí nulové hodnoty časového měřítka a na střed šipky, dále upravit měřítko: zde 2 pixely odpovídají jednomu kroku (5 minut). Nyní můžeme vypočítat hodiny a minuty, případně upravit formát na úvodní nuly.

V proměnné dtArray[0] je uloženo zvolené datum jako výsledek testu ve funkci keybInp(), nebo setDate() po výběru datumu kliknutím na kalendář. K datumu jsou přidány hodiny a minuty a výsledek je vložen do pole formuláře #dateTime.

Drag&drop není zcela běžná a bezproblémová metoda. Jednotlivé prohlížeče se nechovají identicky. Např. pokud není ošetřeno, je možné objekt (obrázek) vytáhnout mimo okno některých browserů. Vytažením vlevo obrázek zcela zmizí a stane se nedostupný, vpravo jej lze někdy ještě narolovat.

updated 16.09.2007