TP

ASP.NET - Ovládací prvky používající JavaScript

Co tento článek ukazuje

Klientské skriptování (obvykle realizované pomocí JavaScriptu) umožňuje některé jednodušší operace provádět ve webových prohlížečích na straně klienta. Tím se výrazně zrychlí odezva aplikace a také se sníží zátěž serveru (protože není potřeba posílat na server dotaz). Při tvorbě klientských skriptů je podstatné uvědomit si rozdíl mezi klientrkým skriptem, nejčastěji JavaScriptem, který je zpracováván ve webovém prohlížeči a serverovým kódem (C#, Vb.Net), který je zpracováván na straně serveru.

Ukázkový ovládací prvek

Ukázková aplikace

Ovládací prvek, na kterém se pokusím demonstrovat práci s JavaScriptem je ovládací prvek (ascx), ve kterém se nachází textové pole a tlačítka + a -. Pomocí JavaScriptu se při kliknutí na tlačítka zvýší nebo sníží číslo vyplněnné v textovém políčku. Dále se za políčkem vypisuje několik odkazů, které na straně serveru nastaví hodnotu v textovém políčku a vyvolají serverovou událost. V ukázkové aplikaci se při vyvolání této události zobrazí červený label s informacemi.

Předávání dat mezi klientem a serverem

Nejprve se podíváme jak lze předávat data mezi klientským a serverovým skriptem. V JavaScriptu i v Asp.Net lze poměrně snadno získat a měnit hodnotu uloženou ve formulářových ovládacích prvcích, například textové pole nebo zkryté pole (input type=hidden), které umožňuje předávat data aniž by data viděl uživatel. Jediným problémem je, že Asp.Net automaticky generuje id ovládacích prvků, takže pokud chcete z JavaScriptu měnit hodnotu v textovém poli pojmenovaném txtNum, musíte vygenerovat část klientského skriptu, která přistupuje k datům.

Následující příklad ukazuje, jak lze pomocí JavaScriptu měnit hodnotu zadanou v textovém políčku. V první ukázce je zobrazný kód z ovládacího prvku (ascx soubor) a v druhé ukázce je vidět jaký kód vygeneruje Asp.Net pokud tento ovládací prvek vložíte do stránky.

<!-- Takto vypada kod v ascx souboru -->
<asp:TextBox runat="server" id="txt"></asp:TextBox>
<input type="button" value="Nastav" onclick="
  var el=document.getElementById('<%=txt.ClientID %>');
  el.value='Ahoj'; " />
<!-- Kod, ktery se vygeneruje muze vypadat takto: -->
<input name="cc2:txt" type="text" id="cc2_txt" />
<input type="button" value="Nastav" onclick="
  var el=document.getElementById('cc2_txt');
  el.value='Ahoj'; " />

V ukázkové aplikaci je v ovládacím prvku následující kód, který používá funkce numInc a numDec. Způsob, kterým se tyto funkce vkládají do stránky je popsán níže.

<!-- Textove pole na zadavni cisla -->
<asp:TextBox Columns="6" Runat="server" ID="txtNum"></asp:TextBox>

<!-- Tlacitka na prciteni a odecteni 1 -->
<input type="button" value="+" onclick="
  numInc(document.getElementById('<%=txtNum.ClientID%>'));">
<input type="button" value="-" onclick="
  numDec(document.getElementById('<%=txtNum.ClientID%>'));">

Pokud byste chtěli místo asp:TextBox, který umožňuje uživateli přímo měnit hodnotu použít neviditelný prvek, vypadal by první řádek v první ukázce takto: <input type="hidden" id="txt" runat="server" />. Asp.Net v současné době neobsahuje pro neviditelné pole ovládací prvek, proto je potřeba použít standardní HTML ovládací prvek, s nastaveným atributem runat=server.
Pozor: Pokud používáte v klientském skriptu pole, které se nezobrazuje uživateli neznamená to, že do něj uživatel-útočník nemůže vložit hodnotu, kterou neočekáváte. Je tedy nutné s těmito daty pracovat s největší opatrností!

Vkládání JavaScriptového kódu

Okno Properties

Pokud máte ovládací prvek, kde je větší množství JavaScriptového kódu (například několik JS funkcí), není vhodné aby se tento kód vkládal do stránky s každým ovládacím prvke, ale stačí, když se tento kód vloží do stránky pouze jednou. Dále je vhodné, když je skript uložen v souboru, který je připojen k assembly jako resource (protože tak můžete mít skript v zvláštním souboru). Při vkládání skriptu do stránky poté stačí pouze načíst soubor z assembly a vložit ho do stránky. Soubor připojíte k projektu jako resource tak, že v okně 'Properties' zvolíte z nabídky 'Build Action' volbu 'Embedded resource'. Při načítání je potřeba dávat pozor na jméno resource, které je ve tvaru Namespace.Soubor.xyz, kde Namespace je jméno výchozího jmenného prostoru (lze jej nalézt ve vlastnostech projektu).

// Zajisti, ze se skript bude vkladat pouze jednou
if (!Page.IsClientScriptBlockRegistered("cont-control"))
{
  // pomoci reflection ziska aktualni assembly
  Assembly asm=Assembly.GetExecutingAssembly();
  
  // nacte z assembly soubor "script.html"
  StreamReader sr=new StreamReader
    (asm.GetManifestResourceStream("UsingJavaScript.script.html"));
    
  // a vlozi do stranky JS blok 
  Page.RegisterClientScriptBlock("cont-control",sr.ReadToEnd());
  sr.Close();
}

Poznámka: Ač chceme vložit do stránky JavaScriptový kód je potřeba vkládat i tag <script> a proto je skript v resources uložený jako HTML soubor.

Vyvolávání post-backu

Další téma tohoto článku je problém, jak z klientského skriptu vyvolat post-back (tedy jak po nějaké akci uživatele odeslat požadavek na server). Jediné HTML prvky, které automaticky odesílají data zpět na server jsou input type=submit a input type=image, nicméně v Asp.Net existují i další ovládací prvky, které potřebují odesílat data na server podobným způsobem. K tomu se v Asp.Net používá klientské skriptování, konkrétně funkce __doPostBack, které jste si mohli všímnout v generovaném HTML kódu Asp.Net stránek.

Tuto funkci není nutné používat přímo, protože v Asp.Net existují metody, které tvorbu takových ovládacích prvků zjednodušují. Pokud chcete ve vašem ovládacím prvku vygenerovat kód, který vyvolá post-back a po odeslání událost zpracovat budete potřebovat implementovat rozhraní IPostBackEventHandler. Toto rozhraní obsahuje jedinou metodu, která je zodpovědná za zpracování post-backu. Ke generování klientského skriptu, který postback vyvolá se používá metoda Page.GetPostBackClientHyperlink. Jak vyvolávat a zpracovávat postback demonstruje následující ukázka:

Jedná se pouze o upravenou část kódu. Pro komletní ukázku se podívejte do přiložených zdrojových kódů.

// Ovladaci prvek, ktery vyuziva post-back
public class CountControl : 
  System.Web.UI.UserControl, IPostBackEventHandler
{
  // Do tohoto ovladaciho prvku se vlozi generovane odkazy 
  protected Literal ltrLinks;
  
  // Vygenerovat odkazy..
  private void Page_Load(object sender, System.EventArgs e)
  {
    StringBuilder sb=new StringBuilder();
    for(int i=1; i<=10; i++)
    {
      // generuje kod, ktery pouziva __doPostBack.
      // Pri kliknuti na generovany odkaz se zavola
      // metoda RaisePostBackEvent (s parametrem 'i')
      sb.AppendFormat("<a href=\"{0}\">{1}</a>",
        Page.GetPostBackClientHyperlink(this,i.ToString()),i);
    }
    ltrLinks.Text=sb.ToString();		
  }
  
  // Metoda z rozhrani IPostBackEventHandler
  // Vola se po kliknuti na odkaz a zpracovava post-back
  // eventArgument je parametr (v tomto pripade cislo)
  public void RaisePostBackEvent(string eventArgument)
  {
    // .. zpracovat kliknuti na odkaz ..
  }
}
  

Všimněte si, že volání funkce __doPostBack za vás obstará samotné Asp.Net a proto, pokud se v některé následující verzi Asp.Net změní způsob jakým je post-back vyvoláván, nebude takový problém aplikaci upravit. Nevýhodou ale je, že pokud v JavaScriptu něco spočítáte, nemůže tuto hodnotu předat serveru přímo jako parametr. K tomuto účelu lze ale použít výše popsanou techniku, kdy si vypočtenou hodnotu uložíte do pole input type=hidden, vyvoláte post-back a na straně serveru uloženou hodnotu opět načtete.

Soubory na stažení a odkazy

Published: Sunday, 5 June 2005, 9:16 PM
Author: Tomas Petricek
Typos: Send me a pull request!
Tags: