Disclaimer: Tento tutoriál předpokládá dobrou znalost HTML a CSS, základní znalost javascriptu a základní povědomí o ASP.NET. Nejedná se o obecný seriál o jQuery, spousta věcí, které si budeme ukazovat, se bude týkat technologie ASP.NET. Rozhodně se též nejedná o kompletní pojetí jQuery, spíš jen počáteční nakopnutí pro ty, kteří neví, kde začít.
jQuery a ASP.NET AJAX
Začneme trochu od lesa. Někdy kolem roku 2006 se ve světě ASP.NET objevil Atlas Framework, který byl později přejmenován na ASP.NET AJAX a dodnes je součástí runtime ASP.NET (komponenty ScriptManager, UpdatePanel atd.).
AJAX ale nebyla jediná věc, kterou tento framework přinesl, velmi brzy se též uvolnila knihovna Ajax Control Toolkit, která umožnila dělat například vyskakovací okna, animace, což jsou věci, které se na webu objevují stále častěji. Samotný ASP.NET AJAX nejsou jen komponenty ScriptManager a UpdatePanel, je to také poměrně rozsáhlá javascriptová vrstva, kterou můžete použít i pro programování na klienstké straně.
Obliba Ajax Control Toolkitu postupně klesá se zmenšující se komunitou, která přešla buď na MVC, nebo začala používat jQuery. A vzhledem k tomu, že jQuery je dnes de facto standardem, stává se jeho znalost velmi důležitá i pro ASP.NET vývojáře.
Já osobně ve svých aplikacích kombinuji výhody obou frameworků – na animace, vyskakovací okna a podobné věci používám jQuery, na AJAXová volání a třeba automatické doplňování textových polí zase ASP.NET AJAX a Control Toolkit. Tyto technologie se navzájem neruší, takže lze využít obou.
Jak začít s jQuery
Pokud chcete jQuery používat, musíte do stránky pochopitelně naimportovat pomocí elementu script soubory této knihovny. Existují v zásadě 2 možnosti:
1. Knihovny jQuery si stáhnete, přibalíte je jako součást aplikace třeba do adresáře Scripts a naimportujete lokálně.
2. Využijete CDN (Content Delivery Network) a naimportujtete skripty například ze serverů Google, Microsoftu nebo jiného poskytovatele. Výhoda takového řešení je, že prohlížeč je typicky ani stahovat nebude – vzhledem k tomu, že jQuery se používá skoro všude, bude mít prohlížeč tyto soubory nacacheované, takže stránka bude načtena rychleji.
Osobně preferuji druhou možnost, takže do MasterPage přidávám následující kód:
<script type="text/javascript" src="http://code.jquery.com/jquery-1.4.1.min.js"></script>
Existují sice novější verze jQuery, ale pro ty není k dispozici nápověda pro IntelliSense ve Visual Studiu. Obecně je jedno, kterou verzi použijete, základy, které si zde ukazujeme, fungují všude.
To min v názvu znamená, že se jedná o minifikovanou verzi, tedy jakousi “komprimovanou” verzi zdrojáků, která zabírá méně místa. Minifikace typicky vyhodí ze souboru nepotřebné bílé znaky (konce řádků, mezery, tabulátory, samozřejmě jen tam, kde to nezmění význam), přejmenuje proměnné na co nejkratší názvy, vyhází komentáře atd.
Kdybyste se v kódu chtěli hrabat, tak je k dispozici nezmenšená verze zdrojáků včetně komentářů.
Selectory
Pokud chceme začít s jQuery, je nutné si pořádně ujasnit, jak fungují selectory. Jistě všichni známe CSS a víme, že když napíšeme následující kód, obarví se všechny nadpisy úrovně 2 na červeno.
h2 { color: Red; }
Selector je v tomto případě h2 a znamená to, že vybíráme všechny elementy h2 ve stránce.
Vybírat elementy můžeme také podle ID – stačí začít znakem #. Následující kód vybere element, který má id rovno test.
#test { color: green; }
Kdybychom napsali například tohle, bude to platit pro všechny odkazy, které jsou kdekoliv uvnitř elementu h2.
h2 a { color: Red; }
Dále lze položky vybírat pomocí atributu class. Následující kód vybere všechny odkazy, které mají v atributu class hodnotu external.
a.external { color: Red; }
Element může mít více tříd, pokud je tomu tak, v HTML to vypadá takto:
<a class="trida1 trida2">odkaz</a>
V CSS by pak selector vypadal takto (případně by mohlo být na začátku a, aby to fungovalo jen na odkazy; takhle to bude fungovat na libovolný element, který má obě třídy).
.trida1.trida2 { color: Blue; }
HTML5 přineslo jednu užitečnou věc, které se říká data atributy. V zásadě si můžete k libovolnému HTML elementu přidat libovolné množství vlastních atributů, jediná podmínka je, aby začínaly data-.
Takže plně validní zápis je například toto (u textového pole si pamatujeme hodnotu, která tam byla původně, abychom pak mohli skriptem zjistit, jestli uživatel to pole změnil nebo ne):
<input type="text" data-originalvalue="23" />
Pokud bychom chtěli selectorem vytáhnout jen políčka, která mají takový atribut, vypadalo by to takto:
input[data-originalvalue] { color: Blue; }
V tomto případě nás hodnota atributu nezajímala, pokud ano, vypadalo by to například takto:
input[type=text] { color: Blue; }
Existují ještě další selectory, ale o těch až za chvíli, nedočkaví se koukou na kompletní seznam.
Proč jsem je zde všechny vypisoval? Protože jQuery je na nich svým způsobem postaveno. Typická práce s jQuery totiž vypadá tak, že si pomocí selectoru vyzobnete určitou množinu elementů a nad ní pak provedete nějaké operace – například se navěsíte na událost onclick, nebo je nějak obarvíte, nastavíte animaci atd.
Manipulujeme s objekty
Funkce css
Začneme jednoduchým příkladem, máme seznam a chceme v něm zvýraznit položku, která má CSS třídu selected.
<ul id="seznam">
<li>První</li>
<li class="selected">Druhá</li>
<li>Třetí</li>
</ul>
<p><input type="button" onclick="ButtonClick();" value="Test" /></p>
<script type="text/javascript">
function ButtonClick() {
$("#seznam li.selected").css("color", "green");
}
</script>
Podstatný je následující řádek:
$("#seznam li.selected").css("color", "green");
První část $(“#seznam li.selected”) vybere množinu elementů li, které mají třídu selected.
Druhá část na tuto množinu aplikuje CSS vlastnost color: green. Navíc funkce css vrací původní kolekci, takže na konec můžete navěsit další kód.
Funkce CSS umí nastavit i více vlastností najednou, vypadalo by to takto:
$("#seznam li.selected").css({ color: "blue", fontWeight: "bold" });
Jako parametr té funkci předáváme objekt se dvěma vlastnostmi – color=blue a fontWeight=bold. Vlastnost fontWeight se v CSS přeloží na font-weight, protože javascript neumožňuje mít v názvech pomlčky, že tam má být pomlčka je naznačeno velkým písmenem.
Funkce animate
Když už umíme nastavit CSS vlastnost, můžeme se podívat na animace – jsou velmi jednoduché. Zkusíme třeba postupně zvětšit velikost písma na 24, a to v průběhu 500 milisekund.
$("#seznam li.selected").animate({ fontSize: 24 }, 500);
Po kliknutí na tlačítko se druhá položka plynule zvětší. Animovat můžete jakékoliv číselné vlastnosti, typicky width a height.
Funkce animate má ještě třetí parametr – tam lze dát buď linear (rovnoměrně) nebo swing (se zrychlením a zpomalením). Čtvrtý parametr je funkce, která se zavolá ve chvíli, kdy je animace dokončena. Objekty, kterých se animace týkala, získáte přes konstrukci $(this). Tu uvidíme ještě mnohokrát.
$("#seznam li.selected").animate({ fontSize: 24 }, 500, "swing", function () {
$(this).animate({ fontSize: 14 }, 500);
});
Funkce attr
Pojďme k něčemu užitečnějšímu, často v aplikacích máme seznam zaškrtávacích políček a rádi bychom přidali tlačítka Označit vše a Zrušit označení.
Funkce attr umožňuje nastavit atribut na nějakou hodnotu.
<ul>
<li>
<input type="checkbox" value="1" name="month1" />
<label for="month1">Leden</label>
</li>
<li>
<input type="checkbox" value="2" name="month2" />
<label for="month2">Únor</label>
</li>
<li>
<input type="checkbox" value="3" name="month3" />
<label for="month3">Březen</label>
</li>
<li>
<input type="checkbox" value="4" name="month4" />
<label for="month4">Duben</label>
</li>
<li>
<input type="checkbox" value="5" name="month5" />
<label for="month5">Květen</label>
</li>
<li>
<input type="checkbox" value="6" name="month6" />
<label for="month6">Červen</label>
</li>
</ul>
<p>
Označit
<a href="#" onclick="ButtonClick('selected'); return false;">vše</a>
/
<a href="#" onclick="ButtonClick(''); return false;">nic</a>
</p>
<script type="text/javascript">
function ButtonClick(value) {
$("input[type=checkbox]").attr("checked", value);
}
</script>
Jeden odkaz volá funkci ButtonClick s parametrem checked, druhý předává prázdný řetězec. Funkce attr nastaví všem checkboxům atribut checked na zadanou hodnotu.
Pokud bych chtěl označit jen březen, vypadalo by to takto – prostě do selectoru přidáme další podmínku.
$("input[type=checkbox][value=3]").attr("checked", value);
Přiznám se, že jsem rád, že v ASP.NET máme komponentu CheckBoxList, která vyrenderuje tu samou smečku inputů a labelů, ale vypadá to lépe.
Rozbalovací sekce – funkce slideUp, slideDown a slideToggle
Velmi častým požadavkem zákazníků jsou rozbalovací sekce – s jQuery je to hračka na pár minut. Funkce slideUp vezme blokový element a jednoduchou animací mu sníží výšku na 0 (takže není vidět). Funkce slideDown dělá pravý opak – animací element opět rozbalí. Pokud si nechceme pamatovat, jestli byl rozbalený nebo sbalený, máme funkci slideToggle, která jej podle jeho aktuálního stavu sbalí nebo rozbalí.
Roztahovatelná sekce může tedy vypadat takto (nejprve styly):
.expandable
{
margin: 10px;
}
.expandable > .content
{
border: 1px solid gray;
padding: 5px;
display: none;
}
.expandable > .header
{
background-color: #335599;
color: White;
font-weight: bold;
padding: 3px;
}
Postatné je, že sekce jsou defaultně sbalené, tj. .content má nastaveno display: none. To znamená, že sekce se vůbec nezobrazuje a nebude v dokumentu ani zabírat místo.
<div class="expandable">
<div class="header">První sekce</div>
<div class="content">
Tento obsah je vidět jen při rozbalené sekci.
</div>
</div>
<div class="expandable">
<div class="header">Druhá sekce</div>
<div class="content">
Tento obsah je vidět jen při rozbalené sekci.
</div>
</div>
Nyní bychom chtěli, aby se po kliknutí na hlavičku sekce .content sbalila či rozbalila. Budeme na ni tedy volat funkci slideToggle. Jak ale detekovat kliknutí na hlavičku? Pomocí funkce click:
$(".expandable > .header").click(function () {
$(this).parent().find(".content").slideToggle(300);
});
Funkce click dostane jako parametr funkci, která říká, co se má stát po kliknutí na tuto sekci. Selector .expandable > .header znamená, že .header musí být přímý potomek .expandable (umožníme tím vnořování rozbalovacích sekcí i to, že .header budeme moci použít i v jiném kontextu).
Přes $(this) se dostaneme k jQuery obálce kolem objektu, na který se událost vztahovala, čili element .header. Obalit jej musíme, abychom na něm měli funkce z jQuery, jinak pracujeme s klasickým DOM objektem (tím, co vrací například document.getElementById)
Protože nechceme rozbalit či sbalit .header, ale .content, musíme nejprve tento .content získat. Asi nejjednodušší je zavolat .parent(), což vrátí rodičovský element, a pomocí funkce find najít to, co hledáme, v tomto elementu, tedy .content.
Na něm už zavoláme ono slavné slideToggle, parametr říká, jak dlouho má animace trvat.
Aby tohle všechno fungovalo, potřebujeme tento skript spustit po načtení stránky. Dát tento skript úplně na konec do sekce body se nedoporučuje, je vhodné jej skustit v události document.ready. Kód, který chceme spustit po načtení stránky, kdy už máme jistotu, že je celý DOM strom připraven, obalíme takto:
$(document).ready(function () {
$(".expandable > .header").click(function () {
$(this).parent().find(".content").slideToggle(300);
});
});
Ono dokonce stačí dát kód obalit jen tímto, ale to není tak výstižné, preferuji první způsob.
$(function () {
// kód
});
Funkce show a hide
Poslední funkce, které si v tomto díle ukážeme, jsou show a hide. Pomocí nich můžeme snadno udělat vyskakovací modální okno. Opět nejdříve styly:
#modal-background
{
display: none;
position: fixed;
top: 0px;
left: 0px;
width: 100%;
height: 100%;
background: #a0a0a0;
filter: alpha(opacity=70);
opacity: 0.7;
z-index: 9999;
}
#modal-popup
{
display: none;
position: fixed;
width: 400px;
left: 50%;
margin-left: -200px;
background: white;
border: 1px solid black;
padding: 10px;
z-index: 10000;
}
První element je poloprůhledné pozadí (vlastnost opacity), které se roztáhne přes celou obrazovku (fixed pozicování, takže nebere v úvahu scrollování stránky).
Druhý element je okénko s šířkou 400px centrované na střed (díky triku se záporným levým okrajem).
<p class="content">Normální stránka</p>
<p><input type="button" value="Vybrat barvu textu" onclick="DisplayPopup();" /></p>
<div id="modal-background"></div>
<div id="modal-popup">
<h3>Vyberte barvu</h3>
<ul>
<li><a href="#" data-color="red">Červená</a></li>
<li><a href="#" data-color="green">Zelená</a></li>
<li><a href="#" data-color="blue">Modrá</a></li>
</ul>
<p><a href="#" onclick="ClosePopup(); return false;">Zavřít</a></p>
</div>
Ve stránce máme odstavec textu a tlačítko, které zobrazí vyskakovací okno. Elementy modal-popup a modal-background se standardně nezobrazí, v CSS stylu mají display: none.
Nyní javascriptové funkce:
function DisplayPopup() {
$("#modal-background").show();
$("#modal-popup").show();
}
function ClosePopup() {
$("#modal-background").hide();
$("#modal-popup").hide();
}
Funkce show zobrazí prvek (dá se dát i časový limit, pokud chcete animované roztažení) a hide jej zase schová (opět je možné mít animaci, my je ale nechceme).
Nejdůležitější je nastavení barvy odstavci ve stránce, o to zde běží. Mohli bychom každému odkazu nastavit onclick ručně a zavolat nějakou funkci, ale opět využijeme jQuery funkci onclick a obsluhu události nastavíme hromadně všem odkazům.
Všimněte si také, že barvu, kterou chceme nastavit, má každý odkaz poznamenanou v atributu data-color.
$(document).ready(function () {
$("#modal-popup a[data-color]").click(function () {
// zjistit barvu z data atributu
var col = $(this).attr("data-color");
// obarvit text
$(".content").css("color", col);
// zavřít okno
ClosePopup();
// zrušit výchozí akci odkazu
return false;
});
});
Po načtení stránky tedy najdeme všechny odkazy, co mají data-color v modálním okně (odkaz pro zavření okna tento atribut nemá, ale obsluhu události na něj dávat nechceme, ten ji má přímo v HTML kódu stránky).
Nejprve si z $(this) zjistíme hodnotu atributu data-color – to umí funkce attr, kterou už známe. Pokud jí dáme jen jeden argument, místo toho, aby hodnotu atributu nastavovala, ji vrací (obdobně funguje v jQuery mnoho funkcí).
Pak funkcí css obarvíme text v odstavci ve stránce, to už známe. Dále zavřeme okno, na tom taky není nic světoborného.
A protože se tato akce vyvolává kliknutím na odkaz, nastalo by přesměrování na jinou stránku – to nechceme, proto vrátíme false, aby odkaz nic nedělal. Podobně jako to musíme udělat, když píšeme obsluhu události onclick přímo v HTML jako atribut.
No a to je celé, máme modální okno, které vyskočí když zavoláme DisplayPopup a umožní změnit barvu ve stránce. A stačilo k tomu jen pár funkcí z jQuery. K pořádné implementaci modálního okna to samozřejmě ještě má daleko. Chtělo by to například, aby se tlačítkem Zpět v prohlížeči dialog zavřel, aby se zavřel třeba i klávesou Escape atd. Ale to už je nad rámec tohoto dílu.