Kamil Kliczbor @ asptip.net

20Nov/100

Krótka historia: jquery.validate + WebForms + zewnętrzy plik js

Jak do tego doszło ?

Post ten powstał z inicjatywy kolegi zadającego pytanie zadane na forum http://codeguru.pl/frmThread.aspx?tid=100619. Odpowiadając mu wydawało mi się, że rozwiązanie jest na tyle oczywiste, ze nie wymaga mojej "interwencji" w jego kod. Wszakże kod to rzecz święta :). Jednak późniejsze boje wykazały, że nie wszystko jest takie oczywiste jak się wydawać mogło na pierwszy rzut oka. Temat oczywiście dotyczy utworzenia standardowej stronki w WebForms-ach, która ma być walidowana przez plugin do jquery - jquery.validate.

Przypadek trywialny: skrypt inline na stronie

W necie przykładów do takiego podejścia można znaleźć na prawdę wiele. Po krótkiej chwili w mojej przeglądarce wylądowało ponad 10 różnych stronek, gdzie podawane przykłady aż biły prostotą. Poniżej umieszczam te linki jeżeli ktoś ma może ochotę sobie popatrzeć jakie istnieją rozwiązania do tego zagadnienia:

  • http://www.dotnetcurry.com/ShowArticle.aspx?ID=310&AspxAutoDetectCookieSupport=1
  • http://jquery.bassistance.de/validate/demo/milk/
  • http://www.webreference.com/programming/javascript/jquery/form_validation/
  • http://stackoverflow.com/questions/1232641/jquery-validate-js-and-asp-net-master-pages
  • http://codeclimber.net.nz/archive/2008/05/14/how-to-manage-asp.net-validation-from-javascript-with-jquery.aspx
  • http://www.theaspnetguy.com/theaspnetguy_root/post/2009/05/25/JQuery-Validate-plugin-to-validate-a-ASPNET-Form.aspx

Przypadek rozszerzony : skrypt w pliku zewnętrznym

No i sprawa zaczęła się komplikować, kiedy trzeba było w elegancki sposób przesunąć skrypt javascript'owy do pliku zewnętrznego. Po kilku chwilach walki, z pomocą następujących wskazówek rozwiązałem problem:

  • http://stackoverflow.com/questions/1232465/
  • http://stackoverflow.com/questions/619816/jquery-validation-plugin-in-asp-net-web-forms
  • http://www.west-wind.com/WebLog/posts/252178.aspx
  • http://docs.jquery.com/Plugins/Validation/rules#.22add.22rules

Główny problem tego zadania polegał w gruncie rzeczy na tym, żeby w jakiś sensowny sposób przekazać identyfikatory inputów do skryptu walidującego. O ile samo wydobycie nazwy kontrolki po stronie klienta np. TextBoxa nie było trudne - <%=tbUserName.ClientId %>, o tyle przypięcie tych idków do jquery.validate wymagało większej gimnastyki.

Rozwiązanie

Zewnętrzny plik JavaScript:

var RegisterForm = {
    _controlsNames: new Array(),
    _registerForm: '',

    set_controlsNames: function (value) {
        RegisterForm._controlsNames = value;
    },

    set_registerForm: function (value) {
        RegisterForm._registerForm = value;
    },

    init: function () {

        $("#" + RegisterForm._registerForm).validate();

        $('#' + RegisterForm._controlsNames.user).rules('add', {
            required: true,
            minlength: 2,
            messages: {
                required: "* Required Field *",
                minlength: "* Please enter at least 2 characters *"
            }
        });

        $('#' + RegisterForm._controlsNames.email).rules('add', {
            required: true,
            email: true,
            messages: {
                required: "* Required Field *"
            }
        });
    }
}

Plik formularza:

<%@ Page Title="Home Page" Language="C#" MasterPageFile="~/Site.master" AutoEventWireup="true"
    CodeBehind="Default.aspx.cs" Inherits="JQueryValidation._Default" %>

<asp:Content ID="HeaderContent" runat="server" ContentPlaceHolderID="HeadContent">
</asp:Content>
<asp:Content ID="BodyContent" runat="server" ContentPlaceHolderID="MainContent">
    <h2>
        Formularz i walidacja z jquery.validate
    </h2>
    <asp:Label AssociatedControlID="RegisterUser" Text="Użytkownik:" runat="server"/>
    <asp:TextBox ID="RegisterUser" runat="server" /><br />
    <asp:Label AssociatedControlID="RegisterEmail" Text="Email:" runat="server"/><asp:TextBox ID="RegisterEmail"
        runat="server" />
    <br />
    <asp:Button ID="RegisterButton" runat="server" Text="Rejestruj" CausesValidation="False" />
    <script src="Scripts/jquery.validate.js" type="text/javascript"></script>
    <script src="Scripts/register.js" type="text/javascript"></script>
    <script type="text/javascript">
    //<![CDATA[
        $(function () {
            var controlsToValidate = {
                user: "<%= RegisterUser.ClientID %>",
                email: "<%= RegisterEmail.ClientID %>"
            };

            RegisterForm.set_controlsNames(controlsToValidate);
            RegisterForm.set_registerForm("<%= this.Master.Page.Form.ClientID %>");
            RegisterForm.init();
        });
    //]]>
    </script>
</asp:Content>

Dla bardziej dociekliwych umieszczam również spakowany projekt.

14Apr/100

Walidator numeru (poprawność numeru) PESEL

Każdy obywatel Polski posiada przypisany numer PESEL, który jest akronimem od "Powszechny Elektroniczny System Ewidencji Ludności". O historii i opisie tego numeru można poczytać np. na stronie wikipedii.
W poniższym kawałku kodu przedstawiony został sposób walidacji tego numeru. Założeniem jest to, że na wejściu pobierany jest ciąg znaków, a na wyjściu zwracana wartość logiczna określa, czy PESEL jest poprawny czy nie. Poniższa metoda została użyta jako extension metod, w związku z czym można ja użyć bezpośrednio na każdym łańcuchu tekstowym.

public static bool IsPeselValid(this string candidate)
{
    if (string.IsNullOrEmpty(candidate) || candidate.Length != 11) return false;

    int[] weights = { 1, 3, 7, 9, 1, 3, 7, 9, 1, 3, 1 };

    long peselNumber;
    bool allCharsAreDigit = long.TryParse(candidate, out peselNumber);
    if (!allCharsAreDigit) return false;

    int sum = 0;
    for (int i = 0; i < weights.Length; i++)
    {
        sum += int.Parse(candidate[i].ToString()) * weights[i];
    }

    return (sum % 10) == 0;
}

Więcej w temacie można poczytać na poniższych stronach: