DatePicker pomocí Calendar control v ASP.NET

3. května 2006

Existuje velmi mnoho typů aplikací, které požadují po návštěvníkovi, aby vyplnil datum do nějakého formuláře. Můžeme ho nechat, ať datum vyplní ručně. To však přináší řadu problémů – návštěvníci jsou líní a nechce se jim vypisovat datum do textového pole a potom také můžou nastat problémy s formátem data. Použít tečku nebo lomítko jako oddělovač? Napsal uživatel datum v našem nebo „západním“ formátu? ASP.NET samozřejmě nabízí například RegularExpressionValidator, kulturní zvyklosti a podobné nástroje, takže žádný problém. Je tu však ještě jedna možnost, jak získat datum od uživatele – takzvaný DatePicker.

Co je DatePicker

DatePicker je nástroj, který po klepnutí zobrazí uživateli kalendář (pravidla v novém formuláři), přičemž uživatel může pohodlně klepnout na datum, které se mu líbí, a aplikace toto datum vyplní za uživatele sama – tedy bez použití klávesnice a ve formátu, který aplikace požaduje.

DatePicker v ASP.NET?

Tento postup se běžně používá ve Windows Forms, tak proč ho neaplikovat i na Web Forms, když je to s využitím ovládacího prvku Calendar opravdu jen pář řádků kódu. Celý problém se dá řešit naprosto stejně jako ve Windows Forms – uživatel klepne na tlačítko (nebo pro zvýšení estetického dojmu na obrázek kalendáře) umístěné vedle textového pole, kde aplikace očekává datum, otevře se nové okno s kalendářem a po výběru data se na původní stránce uloží do textového pole hodnota vybraná návštěvníkem a okno s kalendářem se opět tiše zavře. Jak sami uvidíte, je to opravdu jednoduchá myšlenka.

Základní stránka

Jako první si ukážeme kód na stránce, která požaduje po uživateli zápis data:

<form id=“form1″ runat=“server“>
 <div>
  <input type=“text“ id=“tbDate“ runat=“server“ />&nbsp;
  <a target=“_blank“ href=“Calendar.aspx“>picker</a>
 </div>
</form>

Je to jednoduchý ASP.NET formulář, na kterém se nachází pouze textové pole a odkaz vedoucí do nového okna. Tato stránka nepotřebuje ke své funkci žádný další aplikační ani XHTML kód.

Stránka s kalendářem

Přejděme tedy k formuláři Calendar.aspx. Nejdříve HTML:

<form id=“form1″ runat=“server“>
 <asp:Literal ID=“scriptHolder“ runat=“server“></asp:Literal>
 <div>
  <asp:Calendar ID=“Calendar1″ runat=“server“ OnSelectionChanged=“Calendar1_SelectionChanged“>
  </asp:Calendar>
 </div>
</form>

Na tomto webovém formuláři se nachází ovládací prvek Calendar, ze kterého bude uživatel datum vybírat. Abychom mohli odchytit výběr uživatele, musíme prvku říct, co spustit, pokud se tak stane – v našem příkladu na událost SelectionChanged bude reagovat metoda Calendar1_SelectionChanged. Dalším prvkem na stránce je Literal. Tento ovládací prvek použijeme jako kontejner, pomocí kterého podstrčíme na stránku po vyvolání události SelectionChanged jednoduchý JavaScript. A to je celé kouzlo naší aplikace – „podstrčený“ JavaScript.

Trocha JavaScriptu

Pokud chceme pomocí JavaScriptu získat přístup k nějakému objektu na stránce a známe id tohoto objektu, můžeme zavolat metodu getElementById objektu document. Chceme-li tedy vepsat nějakou hodnotu do textového pole na naší stránce, můžeme použít například takovýto JavaScriptový kód:

document.getElementById(„tbDate“).value = „ahoj“;

Další krok, jenž musíme vykonat, je získání objektu umístěného na stránce, která si DatePicker „vyžádala“. V JavaScriptu představuje aktuální okno prohlížeče objekt window. Tento objekt dále zpřístupňuje přes vlastnost opener odkaz na objekt okna, které „zapříčinilo“ otevření tohoto aktuálního okna. A to je přesně to, co my potřebujeme. Získat ze stránky s kalendářem odkaz na původní okno. Pak už je jen dílem okamžiku najít na této stránce textové pole, do které vložíme nějakou hodnotu. O „hledání“ prvku se opět postará metoda getElementById. Náš JavaScript by tedy mohl vypadat nějak takto:

window.opener.document.getElementById(„tbDate“).value = „ahoj“;

Teď to všechno dáme dohromady a napíšeme kód formuláře Calendar.aspx. Nejdříve opět předhodím kód a pak si ho projdeme:

protected void Calendar1_SelectionChanged(object sender, EventArgs e)
{
 string script = @“
  <script type=’text/javascript‘ language=’javascript‘>
   window.opener.document.getElementById(„“tbDate““).value = „“%%DATE%%““;
   window.close();
  </script>
 „;
 
 scriptHolder.Text = script.Replace(„%%DATE%%“, Calendar1.SelectedDate.ToShortDateString());
}

Jediná metoda, která je pro náš momentální účel důležitá, je obsluha události SelectionChanged ovládacího prvku Calendar. Nejdřív sestavíme JavaScriptový kód, který je prakticky stejný jako v předchozím případě, jen s tím rozdílem, že ještě zavírá okno s kalendářem. Jen pro vizuální přehlednost používám v základním řetězci se skriptem „zástupce“ %%DATE%%, kterého hned na dalším řádku nahradím vybraným datem pomocí metody String.Replace(). Výsledný JavaScript poté pošlu do ovládacího prvku Literal, který jsem nazval jednoduše scriptHolder. Poté, co se stránka načte, spustí se tento skript, datum se napíše do textového pole „otevírací“ stránky a okno se automaticky uzavře.

Souhrn

Tato technika je opravdu jednoduchá a je vcelku dobrým představitelem úsloví „hodně muziky za málo peněz“. Pro uživatele bude jistě příjemné, pokud jim poskytnete tuto možnost namísto „otrockého“ vypisování data do textového pole a vás to opravdu nestojí moc námahy. Tento postup má samozřejmě jisté mezery, šlo by například vytvořit nový prvek, dědící z původního kalendáře, který by po klepnutí na datum nevolal server, ale spouštěl podobný klientský skript přímo. Je to sice zprvu složitější, tento nový prvek by však byl jednodušeji „znovupoužitelný“ v jiných projektech a výkon by se bez prakticky zbytečného volání serveru jen zvýšil.

Starší komentáře ke článku

Pokud máte zájem o starší komentáře k tomuto článku, naleznete je zde.

Předchozí článek Odkaz Více
Další článek krausik.cz
Štítky: Články

Mohlo by vás také zajímat

Nejnovější

1 komentář

  1. Petr

    Pro 16, 2009 v 17:52

    Super, presne takovou hracku jsem hledal a diky tobe nasel ;) PN

    Odpovědět

Napsat komentář

Vaše e-mailová adresa nebude zveřejněna. Vyžadované informace jsou označeny *