• Master Coders - Niezawodne oprogramowanie dla firm

Kategoria: Uncategorized

Document.ready() vs pageLoad() – deatchmatch bibliotek Ajax

Często zdarza się że w projekcie ASN.NET Ajax, oprócz Microsoft Ajax Library używamy jeszcze jQuery . Jest to genialna biblioteka, zachwalana przez wszystkich dot netowych guru jak Scott Gunthrie oraz Omar Al Zahir. Wcześniej czy później napotkamy metody document.ready() oraz pageLoad(). I powstaje pytanie czy można ich używać razem.Otóż TAK! Czy to to samo? Niekoniecznie. Pod maską document.ready() jest zdarzenie DOMContentLoaded, jeśli przeglądarka je obsługuje. Jeśli nie, wywoływane jest zdarzenie window.onLoad. Metoda pageLoad() wykorzystuje uniwersalne odwołanie setTimeout z wartością 0 sekund. Co powoduje że skrypt czeka na załadowanie się całego modelu DOM, przed wywołaniem. Z tym wiąże się 1 pułapka – pageLoad() wywołuje się więcej niż raz – także po każdym postbacku.Na przykład na takiej stronie:


<script type="text/javascript"> <br /> function pageLoad() { <br /> // to zadziała więcej niż raz <br /> } <br /></script>

<asp:scriptmanager runat="server">

<asp:updatepanel runat="server">
<contenttemplate>
<asp:button runat="server" id="Button1">
<asp:literal runat="server" id="TextBox1">
</asp:literal>
</asp:button>

metoda pageLoad() zostanie wywołana po każdym naciśnięciu buttona. Oczywiście w pewnych sytuacjach taka funkcjonalność jest idealna, np.


<script type="text/javascript">
function pageLoad() {
$('#TextBox1').unbind();
$('#TextBox1').datepicker();
}
</script>

<asp:ScriptManager runat="server" />

<asp:UpdatePanel runat="server">
<ContentTemplate>
<asp:Button runat="server" ID="Button1" />
<asp:TextBox runat="server" ID="TextBox1" />
</ContentTemplate>
</asp:UpdatePanel>

Wtedy po postbacku plugin datepicker zostanie ponownie powiązany z textboxem. Inaczej utracilibyśmy tą funkcjonalność.
Podsumowując, pageLoad(), jest metodą wywoływaną wielokrotnie, po załadowaniu strony, oraz przy każdym postbacku. Działa tak samo w każdej przeglądarce. Natomiast document.ready() zawiera optymalizacje dla przeglądarek i jest wywoływana tylko raz po załadowaniu strony. Ciekawostka : Jeśli chcemy osiągnąć funkcjonalność document.ready() (jednokrotne przetwarzanie) bez korzystania z biblioteki jQuery ? Wtedy należy wykożystać metodę S Sys.Application.init. Aby z niej korzystać użyj tego snipletu z kodem:


<asp:ScriptManager runat="server" />

<script type="text/javascript">
Sys.Application.add_init(function() {
// Kod inicjujący, do uruchomienia tylko raz
});
</script>

Walidacja po stronie serwera z wykorzystaniem kontrolek CustomValidator oraz ValidationCalloutExtender

Podczas tworzenia reguł walidacji w aplikacji webowej, może się zdarzyć, że standardowe Validatory nie wystarczają, aby zapewnić w pełni funcjonalną walidację. Typowym przykałdem jest sprawdzenie czy czy login już istnieje w bazie. Zwłaszcza, jeśli budujemy aplikację Ajax, która z definicji ma działać bez przeładowania strony. Z pomocą przychodzi. kontrolki CustomValidator oraz validatorCalloutExtender. Aby to osiągnąć wykonujemy następujące czynności.

Dodajemy rządne Pole tekstowe i validator do strony. Całość otaczamy update panelem:


<asp:scriptmanager id="ScriptManager1" runat="server">
<asp:updatepanel id="UpdatePanel1" runat="server">
<contenttemplate>
<asp:textbox id="TextBox1" runat="server">

<asp:button id="Button1" runat="server" text="Button" onclick="Button1_Click">
<asp:customvalidator id="CustomValidator1" controltovalidate="TextBox1" display="None" runat="server" errormessage="
This is the text in your Validator Callout Extender error.
"
ClientValidationFunction="ValidateTextBox" />
<cc1:validatorcalloutextender id="ValidatorCalloutExtender1" targetcontrolid="CustomValidator1" runat="server">
</cc1:validatorcalloutextender>
</asp:customvalidator>

Następnie tworzymy skrypt walidacyjny :


var resultOfTheCallBack;

function ValidateTextBox(sender, args)
{
var textBoxValue = document.getElementById('TextBox1').value;

// call server callback method passing the value in your textbox
YourCallBackMethod(textBoxValue);

if(resultOfTheCallBack == 'Valid')
args.IsValid = true;
else
args.IsValid = false;
}

W Evencie Page Load dodajemy kod generujący metodę javascript obsługującą przetwarzanie wa


string callBackReference = Page.ClientScript.GetCallbackEventReference(this, "arg", "CallBackEventReference", "context");
string yourCallBackScript = "function YourCallBackMethod(arg, context) { " + callBackReference + "; }";
Page.ClientScript.RegisterClientScriptBlock(this.GetType(), "YourCallBackMethod", yourCallBackScript, true);

Na Końcu implementujemy interfejs ICallbackEventHandler


// ICallbackEventHandler Members
public string GetCallbackResult()
{
return _callBackStatus;
}

public void RaiseCallbackEvent(string eventArgument)
{
// TUTAJ WSTAW KOD WALIDACYJNY
if (eventArgument == "junnark")
_callBackStatus = "Valid";
}

To wszystko! .
Najważniejszą metodą jest GetCallbackResult() która przesyła wynik przetwarzania z powrotem do klienckiej metody zdefiniowanej w Page Load.

Walidacja po stronie klienta za pomocą ValidatorCalloutExtender

W Pakiecie AjaxControlToolkit będącego obecnie częścią Microsft AJAX Library znajduje się fajna kontrolka ValidationCalloutExtender. Pozwala ona na wykorzystanie sztandarowych walida torów ASP.NET (RegualExpressionValidator, RequiredFieldValidator itp. ) w scenariuszach Ajaxowych, tzn. do walidacji po stronie klienta. Wszystko jest fajne dopóki walidowany formularz jest wysyłany zwykłym submitem. Problem pojawia się, gdy chcemy zaprogramować przycisk w javascripcie i np. wykorzystać dane do wywołania metody sieciowej. Jak wtedy wywołać nasze Validatory ?Oficjalna dokumentacja milczy na ten temat. Dopiero do głębna analiza kodu javascript dostarczonego z serwera, daje Man bardzo ciekawą metodę:


function Page_ClientValidate();

Która zwraca true jeśli formularz został walidowany poprawinie, lub pokazuje „dymki ”:

I zwraca false jeśli formularz nie został poprawnie walidowany. W tym wypadku nasza funkcja obsługi zdarzenia wyglądała by mniej więcej tak.


function bt_button1_click(sender,e) {
if (Page_ClientValidate()) {
//zrob cos z danymi formularza
}
}