morzel.net

.net, js, html, arduino, java... no rants or clickbaits.

Kod skryptu aktualizowany w UpdatePanelu

Załóżmy, że z jakiegoś powodu musisz umieścić w obszarze kontrolki UpdatePanel funkcję JavaScript, której kod będzie się zmieniał przy każdej aktualizacji panelu. Funkcja ta ma być wywoływana w odpowiedzi na zdarzenie onclick jakiegoś elementu, który znajduję się poza UpdatePanelem...

Pierwsza rzecz, która przychodzi na myśl to umieszczenie skryptu w kontrolce Literal znajdującej się w aktualizowanym fragmencie strony:

protected void Button1_Click(object  sender, EventArgs e)
{
   string s = "<script type='text/javascript'> function " +
      "test() { alert('" + DateTime.Now + "') };</script>";

   Literal1.Text = s;
}

Niestety, przy próbie wywołania funkcji test() pojawi się błąd (przeglądarka jej nie znajdzie). Dzieje się tak dlatego, że aktualizacja UpdatePanelu to tak naprawdę podmiana właściwości innerHTML warstwy (div), która reprezentuje ten panel po stronie klienta. Wnętrze tej warstwy będzie zawierać fragment skryptu jednak przeglądarka nie będzie sobie zdawać sprawy z jego obecności.

Oto fragment przechwyconej za pomocą narzędzia Fiddler, odpowiedzi serwera na postback pochodzący z UpdatePanelu:

HTTP/1.1 200 OK
Server: ASP.NET Development Server/9.0.0.0
Date: Mon, 29 Sep 2008 13:28:26 GMT
X-AspNet-Version: 2.0.50727
Transfer-Encoding: chunked
Cache-Control: private
Content-Type: text/plain; charset=utf-8
Connection: Close

10c
238|updatePanel|UpdatePanel1|
<input type="submit" name="Button1" value="upa1" id="Button1" />

<script type='text/javascript'> function test() { alert('2008-09-29 15:28:26') };</script> | 22a 216|hiddenField|__VIEWSTATE|/wEP...

Widać wyraźnie, że treść skryptu została wysłana do klienta...

Co zrobić by wywołanie funkcji test(), która pojawiła się po aktualizacji UpdatePanelu, zadziałało prawidłowo? Zamiast dosłownie wpisywać treść skryptu w aktualizowany obszar skorzystaj z metody ScriptManager.RegisterStartupScript:

protected void Button1_Click(object  sender, EventArgs e)
{
   string s = "<script type='text/javascript'> function " +
      "test() { alert('" + DateTime.Now + "') };</script>";

   ScriptManager.RegisterStartupScript(this, typeof(Page),
      "abc", s, false);
}

Tym razem wywołanie metody test() zakończy się powodzeniem (użytkownik zobaczy alert z datą ustawianą w chwili aktualizacji panelu).

O znaczeniu poszczególnych parametrów metody ScriptManager.RegisterStartupScript możesz poczytać tutaj.