이번 시간에 같이 다루어볼 내용은....  현업에서 많이들 궁금해 하셨던 부분인....

"유효성 검사 후에 나만의 스크립트를 추가적으로 실행시킬 수 없을까???"

라는 부분에 대한 팁입니다.

일반적으로, 폼안에 놓여진 입력 컨트롤들의 유효성 검사를 위해서 ASP.NET validator들을 사용하시곤 하시는데요. 그 컨트롤을 사용할 경우에는, 추가적으로 여러분만의 스크립트를 실행하거나 하기가 좀 어렵다는 문제가 있었습니다. 그러니깐, 예를 들자면, 사용자가 어떤 버튼을 눌렀을 경우에, 기본적인 유효성 검사 수행 후에 "정말로 삭제하시겠습니까?"와 같은 사용자 컨펌을 한번 더 받고 싶다고 할 경우, 그러한 처리를 하기가 용이하지 않았다는 것이지요... 그랬었죠???

무슨 말인지 잘 이해가 가지 않는다구요?? 그렇다면, 직접 한번 해보시도록 하지요~~

일단, 다음과 같이 폼을 간단하게나마 꾸며보시기 바랍니다. 예를들면, 메일링 리스트 가입폼을 만든다고 해보도록 하시지요~ ^^

코드까지 보여드릴 필요는 없겠지만, 혹시라도 코드를 작성하기 귀찮아하시는 분들을 위해서... 일단 보여드립니다. ^^

<%@ Page language="c#" Codebehind="subscribe.aspx.cs" AutoEventWireup="false" Inherits="AsianaIDTex01.subscribe" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" >
<HTML>
    <HEAD>
        <title>subscribe</title>
        <LINK href="Style/Styles.css" type="text/css" rel="stylesheet">
        <script language="javascript">
            function ConfirmUser()
            {
                if(confirm("가입하시겠습니까?"))
                    return true;
                else
                    return false;
            }
        </script>
    </HEAD>
    <body MS_POSITIONING="FlowLayout">
        <form id="Form1" method="post" runat="server">
            <table cellpadding="5" cellspacing="1" width="300">
                <tr>
                    <td colspan="2"><b>Mailing에 가입하기</b></td>
                </tr>
                <tr>
                    <td width="70" align="center">메일주소</td>
                    <td>
                        <asp:TextBox runat="server" ID="UserMail"></asp:TextBox>
                        <asp:RequiredFieldValidator id="RequiredFieldValidator1" runat="server"
                            ErrorMessage="* 메일주소 기입은 필수" ControlToValidate="UserMail"
                            Display="None"></asp:RequiredFieldValidator>
                        <asp:RegularExpressionValidator id="RegularExpressionValidator1"
                            runat="server" ErrorMessage="* 메일주소의 형식이 올바르지 않음"
                            ValidationExpression="\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*"
                            ControlToValidate="UserMail" Display="None">
                        </asp:RegularExpressionValidator></td>
                </tr>
                <tr>
                    <td align="center">비밀번호</td>
                    <td>
                        <asp:TextBox runat="server" ID="PWDS" TextMode="Password"
                            Width="100"></asp:TextBox>
                        <asp:RequiredFieldValidator id="RequiredFieldValidator2" runat="server"
                            ErrorMessage="* 비밀번호는 기입 필수" ControlToValidate="PWDS"
                            Display="None"></asp:RequiredFieldValidator></td>
                </tr>
                <tr>
                    <td colspan="2" align="right">
                        <asp:Button Runat="server" ID="SubscribeButton" Text="등록"
                            Width="100" CausesValidation="False"></asp:Button>
                        <asp:Button Runat="server" ID="MainButton" Text="메인 페이지로"
                            Width="100" CausesValidation="False"></asp:Button>
                    </td>
                </tr>
                <tr>
                    <td colspan="2" align="center">
                        <asp:ValidationSummary runat="server" id="ValidationSummary1"
                            DisplayMode="List"></asp:ValidationSummary></td>
                </tr>
            </table>
        </form>
    </body>
</HTML>

그리고, 각각의 버튼 컨트롤을 클릭해서, 버튼이 클릭되었을 경우, 실행할 코드 비하인드 쪽을 다음과 같이 작성하도록 합니다.

    private void MainButton_Click(object sender, System.EventArgs e)
    {
        Response.Write("메인 페이지로 이동할까 합니다");
    }

    private void SubscribeButton_Click(object sender, System.EventArgs e)
    {
        Response.Write("축하합니다. " + Server.HtmlEncode(UserMail.Text) + " 는 가입처리 되었습니다");
    }

소스 중에 보시면 ConfirmUser() 이라는 자바스크립트가 보일 겁니다. 그 스크립트는 사용자에게 정말로 가입할 것인지를 재차 확인하는 메시지박스를 띄우는 역할을 하구요. 만일, 사용자가 [확인]을 누르면 포스트백을 처리하고, 사용자가 [취소]를 클릭하면 폼 전송을 없었던 일로 처리하는 역할을 하고자 합니다.

문제는 어떻게 그 스크립트를 추가적으로 수행하게 할 수 있느냐 일 것입니다.

이 문제를 풀어내기 위해서는, 과연 ASP.NET이 기본적으로 Validator들이 사용된 페이지에서 버튼 컨트롤을 위해 어떤 HTML을 생성해 내느냐를 알아내는 것이 필요합니다. 프로그램이란 뭔가 정규화된 규칙에 따라 움직이는 것이기에, Validator가 적용된 폼에서 ASP.NET이 버튼 컨트롤에 적용하는 특성들을 살펴보면, 뭔가 힌트를 얻을 수도 있을테니까요.

일단, 위에서 작성한 현재의 페이지를 한번 확인해 보도록 하겠습니다. 다같이 페이지를 컴파일하고 실행해 보도록 해요~~

"등록" 버튼은 CauseValidation 속성이 true인 상태로 존재하기에, 모든 클라이언트 유효성 검사를 수행하게 될 것이구요. "메인 페이지로"라는 버튼은 CauseValidation=false 이기에, 유효성 검사를 수행하지 않고, 무조건 서브밋이 수행될 것입니다.

즉, 현재 폼에는 유효성 검사를 수행하는 버튼과 유효성 검사를 무시하는 버튼이 각각 존재한다는 것이지요. 이 상태에서 [HTML 소스보기]를 통해서 과연 ASP.NET이 이러한 각각의 버튼을 위해서 어떤 코드들을 자동으로 생성해 주었는지를 확인해 봅시다. 그것을 알고나면, 뭔가 실마리를 잡을 수 있을지도 모르니까요 ^^

브라우저의 메뉴에서 [보기] [소스(C)]를 클릭하셔서, 생성된 HTML 소스를 확인해 보시기 바랍니다. 특히나, 버튼 컨트롤이 생성된 부분의 소스를 말이지요. 그 부분은 다음과 같을 것입니다. ^^

버튼 컨트롤의 생성 코드만을 따로 떼어내서 보면 다음과 같을 겁니다.

<input type="submit" name="SubscribeButton" value="등록"
    onclick="if (typeof(Page_ClientValidate) == 'function') Page_ClientValidate(); "
    language="javascript" id="SubscribeButton" style="width:100px;" />
<input type="submit" name="MainButton" value="메인 페이지로" id="MainButton"
    style="width:100px;" />

그렇습니다. 딱 눈에 띄지요????  바로!!! 파란색의 코드가 핵심이 되겠습니다.

즉, ASP.NET은 유효성 검사를 수행할 버튼 컨트롤들에 대해서 파란색과 같은 코드를 일괄적으로 추가해준다는 것입니다. 만일, 그 파란색 코드에서 사용되고 있는 Page_ClientValidate이나 Page_ClientValidate()라는 것들은 무엇을 하는 녀석들인가?라고 궁금해 하신다면, 그 부분은 스스로, for yourslef, 외롭게, 자진해서, 고독하게 직접(-_-;) 찾아서 살펴보셔야 할 것입니다. 참고로, 그들의 역할을 알아내려면 ASP.NET이 내부적으로 사용하고 있는 스크립트 코드들을 분석해 볼 필요가 있습니다. (아마도 그 파일의 이름은 WebUIValidation.js일 것입니다)

하지만, 굳이 그것을 분석해 보지 않아도 대략적으로 우리는 이 스크립트 코드의 역할을 눈치챌 수 있을 것이기에, 시간이 나시는 분들은 한번 맘 굳게 잡고, 그것을 분석해 보셔도 좋을 것이지만, 우리는 그냥~ 그냥~ 건너가 보도록 하겠습니다. 단지, 바로 그 부분이 실제 유효성 검사를 수행하는 스크립트라고만 인식하고 말입지요~~~

그렇다면!!!

어쨌거나 이 시점에서 우리는 다음과 같은 가정을 해 볼 수 있습니다.

"버튼 서버 컨트롤에 onclick="if (typeof(Page_ClientValidate) == 'function') Page_ClientValidate(); " 라는 코드를 넣을 수 있다면, 그 버튼은 유효성 검사를 무조건 수행한다"

그렇심다. 만일, A 라는 버튼이 있고, 그 버튼의 CauseValidation=false 라 하더라도, 위의 코드를 그 버튼에게 추가해주기만 한다면, A 라는 버튼이 유효성 검사를 수행하는 컨트롤처럼 동작할 수 있다는 것입니다.

그렇다면, 어디 한번 그렇게 해볼까요? 현재 폼에 있는 버튼 중 MainButton이라는 아이디의 ASP.NET 버튼 서버 컨트롤은 CauseValidation=false로 설정되어져 있는 컨트롤입니다. 바로, 우리가 테스트하기에 딱 좋은 컨트롤이라 이거지요~~ 이 컨트롤이 CauseValidation=false로 설정되어져 있음에도 불구하고, 위의 코드를 이 버튼에게 강제적으로 박아준다면... 정말로 이 컨트롤이 마치 CauseValidation=true 인 것처럼 동작할까요????  호오.. 점점 흥미진진해 지고 있죠???  그렇다면, 어디 한번 시도해 봅시다.

Page_Load 이벤트 처리기에 다음과 같은 코드를 작성해서, MainButton 버튼 컨트롤이 onclick="if (typeof(Page_ClientValidate) ... 과 같은 이전의 코드를 가지도록 해보자구요~

    private void Page_Load(object sender, System.EventArgs e)
    {
        // 여기에 사용자 코드를 배치하여 페이지를 초기화합니다.
        this.MainButton.Attributes["onclick"] =
            "if (typeof(Page_ClientValidate) == 'function') Page_ClientValidate();";
    }

이렇게 하시고, 페이지를 컴파일하고 실행해 보면 어떤 결과가 나타나게 될까요???

그렇습니다. 분명 MainButton은 유효성 검사를 무시하는 컨트롤임에도 불구하고, 완전하게 유효성을 검사하는 컨트롤처럼 동작하게 된다는 것입니다. ^^;

이 사실을 통해서 알 수 있는 것은, 여러분이 추가적으로 어떤 스크립트를 추가하고 싶다면, 이 방법을 참고로 하여, 얼마든지 추가할 수 있다는 것입니다.

참고!!

여러분 중에는 이렇게 복잡하게 하지 않아도, 유효성 검사 컨트롤 기능을 살리면서, 추가적으로 스크립트를 수행하게 하는 방법이 있다고 하시면서~~ 저를 째려보시는 분들도 있을 수 있습니다. 그 분들은 아마도 CauseValidation을 true로 둔 상태에서, this.MainButton.Attributes["onclick"] = "스크립트 코드" 라고 해 주어도 자신의 스크립트를 동작하게 할 수 있다는 사실을 아는 분들이시겠지요~~

하지만, 그 방법으로는 유효성 검사 이후에 나만의 스크립트를 수행할 수 없습니다. 오직, 유효성 검사 이전에만 가능하지요... 저는 지금 유효성 검사 이후에 추가 스크립트를 수행하는 방법을 설명드리고 있는 것이랍니다. ^^

물론, 제가 제시하는 방법이 정답인 것은 결코 아니랍니다. ^^;;; 이점 주의~~!!!!

예를 들어 달라구요????  흠... 그렇습니다. 적절한 예제만한 스승도 없지요. 그렇다면, 이제 최종 예제를 한번 해보도록 하겠습니다. 그것은 .

1. "등록" 버튼이 클릭될 경우, 모든 유효성 검사를 수행하게 하고...
2. 유효성 검사 통과 후에 "정말로 등록하시겠습니까?" 라는 컴펌을 받아서 포스트백을 시키거나 취소한다

가 되는 것이지요.

그렇다면, 어디 한번 해봅시다.

우선, 기존에 테스트했던 것들을 좀 정리해야 하겠네요. 다음과 같이 일단 정리하고 시작하시죠

1. Page_Load 이벤트 처리기 안의 코드를 모두 주석처리(혹은 제거) 합니다.
2. SubscribeButton 버튼의 CauseValidation 속성 값을 false로 변경합니다.

준비되셨으면 이제 코드로 들어갑니다.

private void Page_Load(object sender, System.EventArgs e)
{
    // 여기에 사용자 코드를 배치하여 페이지를 초기화합니다.
    string orginValidateCode;
    orginValidateCode = "if (typeof(Page_ClientValidate) == 'function') ";
    orginValidateCode += "if(!Page_ClientValidate()) return false;";

    string MyScriptCode;
    MyScriptCode = "if(!ConfirmUser()) return false;";

    this.SubscribeButton.Attributes["onclick"] = orginValidateCode + MyScriptCode;
}

코드 비하인드를 이렇게 작성하셨다면, 이제 HTML 페이지로 가서 우리가 추가할 실제 스크립트인 ConfirmUser() 스크립트를 추가해 주어야 할 것입니다. 그렇다면, 다음과 같이 작성해 보도록 해요~ HTML 페이지에 말이죠(저의 경우는 SubScribr.aspx 페이지입니다. 위에서 이미 작성해두신 분은 그냥 보기만 하세요~)

<script language="javascript">
    function ConfirmUser()
    {
        if(confirm("가입하시겠습니까?"))
            return true;
        else
            return false;
    }
</script>

이렇게 작성하시고 해보시면, 우리가 원하던 대로 멋지게 동작하는 것을 확인하실 수 있을 것입니다. 한번 테스트들 해보세요. 멋지게 동작하지요???

근데, 코드를 보시면서 약간 의아해하시는 분들이 있어보입니다.  어째서~~

if (typeof(Page_ClientValidate) == 'function') Page_ClientValidate() 

가 아니라...

if (typeof(Page_ClientValidate) == 'function') if(!Page_ClientValidate()) return false;

와 같이 코드를 작성한 것일까???

if(!Page_ClientValidate()) return false 라는 부분이 의아하신 분들 있죠???

그 부분을 바꾼 이유는 유효성 검사 수행 후, 유효성 검사가 실패했다면, 다음 스크립트로 계속 진행하지 않고, 그 즉시 리턴하도록 하기 위해서 그렇게 한 것입니다. 잘 이해가 가지 않는다 하시면, 그 부분을 원래대로(즉, if (typeof(Page_ClientValidate) == 'function') Page_ClientValidate() )으로 바꾸어서 한번 해보세요. 그러면, 유효성 검사에 걸렸을 때에도 "정말로 등록하시겠습니까?"라는 메시지박스가 나오는 것을 보실 수 있을 것입니다. ^^

유효성 검사를 통과하지 못했을 경우에만 컨펌 메시지박스가 나오지 않는 것이 좋겠죠? 해서, 우리는 인라인 스크립트 내에서 유효성 검사의 리턴값을 받아서, 그 값이 false(유효성 검사 통과못함)라면, 그 즉시 인라인 스크립트 자체를 빠져나오게 하기 위해서 그와 같이 코드를 조금 추가한 것입니다 ^^ 조금은 이해가 되시죠??

이것은 우리가 추가할 나만의 스크립트의 경우도 마찬가지입니다. 우리가 추가할 스크립트를 ConfirmUser() 라고 작성하지 않고, if(!ConfirmUser()) return false; 라고 작성한 이유도 마찬가지라는 이야기이지요. 만일, 인라인 스크립트에서 리턴을 하지 않으면 자동으로 무조건 스크립트가 끝난 뒤, 포스트백이 일어나거든요...  직접, 바꿔서 해보시면 이유를 아실 거라고 생각합니다. (직접 이것 저것 테스트해 보는 것이 무척 중요합니다 ^^)

어쩌면, 조금은 머리가 아플수도 있고, 뭔가 머리가 조금 복잡해지는 느낌이 드실 수도 있을 겁니다. 하지만, 곰곰히 생각해 보시고, 지금 알려드린 부분을 이렇게 바꿨다, 저렇게 바꿨다 하시면서 테스트 해 보시면, 오래지 않아, 완전하게 이해하실 수 있고, 수많은 테크닉을 더 추가하실 수도 있을 겁니다.

'.net' 카테고리의 다른 글

HttpModule 구현 및 적용  (0) 2007.05.03
ASP.NET 런타임 내부 이해하기  (0) 2007.05.03
날짜 문자열을  (0) 2007.05.03
Bound Controls  (0) 2007.05.03
Repeater Control (II)  (0) 2007.05.03

+ Recent posts