본문 바로가기

ASP.NET_ 낱말퍼즐/화면구성

ASP.NET으로 '낱말잇기 퍼즐'만들기_ Default.aspx / PuzzleWrite.aspx / PuzzleView.aspx



자~ 이제 낱말퍼즐을 만들 방향을 알았다면, 프로그램을 하기 앞서 페이지 구성을 해보자.


글쓰기 페이지

- DropDownList를 사용하여 5~9까지 중에서만 선택 할 수 있도록 한다. 
- 순차적인 진행을 위해 '번호생성'과 '출제완료'버튼은 visible을 false로 시작한다.
- 문제는 한글과 영문으로만 작성가능하며, 둘 중 하나로 통일해줘야 한다.
(그렇지 않을 경우 다음단계로 이동하지 못하도록 자바스크립트로 제어) 

'번호생성' 버튼의 onclick 이벤트가 발생하기 전에 OnClientClick으로 sendit()함수를 호출한다.
sendit() 함수에서 return 하는 값이 "true"가 아니면 OnClientClick 뒤에있는 onclick 이벤트가 실행되지 않는다.
puzzleAnswer은  웹에서 입력받은 각 칸마다의 값들을,
모아 받아오기 위하여
runat="server"가 추가된 컨트롤(puzzleAnswer)을 말한다.
puzzleAnswer에 각각의 값을 모아두는 이유는, 출제 된 문제의 답을 DB로 보내 insert할 때 필요하기 때문이다. 
태그에 runat="server" 속성을 추가하면, 컨트롤이 서버컨트롤로 변환된다. 서버컨트롤이 되면 postback이 발생해도 값이 유지된다.
PuzzleWrite.aspx_ 글쓰기(문제출제) 
<body>
<div id="contsTitleBox">
    <div class="contsTitleStr"><a href="/Default.aspx/">[낱말퀴즈목록]</a></div><br />
</div>
    <form id="form1" runat="server">
    <div>
    칸 수 선택:
    <asp:DropDownList ID="TableNum" runat="server">
        <asp:ListItem>5</asp:ListItem>
        <asp:ListItem>6</asp:ListItem>
        <asp:ListItem>7</asp:ListItem>
        <asp:ListItem>8</asp:ListItem>
        <asp:ListItem>9</asp:ListItem>
    </asp:DropDownList>
    <asp:Button ID="BtnCreateTable" runat="server" Text="칸생성" onclick="BtnCreateTable_Click" />
    <asp:Button ID="BtnCreateNum" runat="server" Text="번호생성" OnClientClick="return sendit();"      onclick="BtnCreateNum_Click" Visible="False" />
    <asp:Button ID="questionEnd" runat="server" Text="출제완료"
            onclick="questionEnd_Click1" Visible="False" />
    <p></p>
    <div id="tablePrint" runat="server" enableviewstate="false"></div>
        <asp:Label ID="Label1" runat="server" Text=""></asp:Label>
    <input type="hidden" id="puzzleAnswer" name="puzzleAnswer" runat="server" />
    <p></p>
    <textarea id="widthQuestion" runat="server"  name="widthQuestion" style="width:30%; height:200px;" visible="False">
    </textarea>
    <textarea id="lenghtQuestion" runat="server"  name="lenghtQuestion" style="width:30%; height:200px;" visible="False">
    </textarea>
    </div>
    </form>
</body>

PuzzleWrite.aspx_javascript_sendit()
testStr의 내용에 /\,/g/\s/g''로 바꿔 준 후 에도, ''라면 조건을 만족하기 때문에
if문 안에 들어가게되고 즉 아무것도 입력되지 않았다는 경고창을 띄우게 된다.
경고창을 띄어준 후에는 if문안의 for문을 돌아돌아 칸안에 ',' 또는 ' '가 입력돼 있을 경우 모두 ''로 바꿔주는 작업을 한다.
chkText는 값이 한글 또는 영문의 범위를 벚어나는지를 검사해준다.(chkText중에서도 11번이 한글과 영문을 체크해준다.) 한글과 영문외에 다른 값이 입력된다면 경고창을 띄우고 false를 return한다.
 

 <script type="text/javascript" src="/Scripts/jquery-1.4.1.min.js"></script>
    <script type="text/javascript" language="javascript">
        function sendit() {
            var lbl_puzzleAnswer = document.getElementById("<%=puzzleAnswer.ClientID %>");
            var test = $('.inputtest').length;
            var testStr = "";
            var testStr1 = "";
            var textCheck = "";
            for (i = 0; i < test; i++) {
                testStr = testStr + $('#test' + i).val() +',';
            }

            if (testStr.replace(/\,/g, '').replace(/\s/g, "") == '') {
                alert("문제를 입력해주세요.");

                for (i = 0; i < test; i++) {
                    $('#test' + i).val('');
                }
                return false;
            }

            testStr1 = testStr.replace(/\,/g, '').replace(/\s/g, "");

            if (!chkText(testStr1, 11)) {
                alert("한글과 영문만 입력가능합니다.");
                return false;
            }
           
            textCheck = testStr1.substr(0, 1); //testStr1의 첫번째 글자까지만을 잘라둔다.

            if (chkText(textCheck, 3)) //textCheck가 한글이라면 textCheck= 3, 영문이라면 textCheck= 12 
           {       
                textCheck = 3;
            }
            else {
                textCheck = 12;
            }

            if (!chkText(testStr1, textCheck)) //testStr1을 textCheck에 저장된 번호로 검사하여, 전체를 한글 or 영문으로 통일한다. 
           {
                var msg = "";
                changeTextColor(test, textCheck);
                if (textCheck == 3) {
                    msg = "한글만 사용이 가능합니다.";
                } else {
                    msg = "영문만 사용이 가능합니다.";
                }
                alert(msg);
                return false;
            }

            testStr = testStr.replace(/\s/g, "")
            lbl_puzzleAnswer.value = testStr.substr(0, testStr.length - 1);              
            //return false;
        }

        function changeTextColor(textLength, textCheckNum) //textCheck를 통해 분류된(잘못입력된) 값은 다른칼라 표기
       {
            var textSentence = "";

            for(i = 0; i < textLength; i++) {
                textSentence = $('#test' + i).val();
                if (textSentence != "") {
                    if (!chkText(textSentence, textCheckNum)) {
                        $('#test' + i).css("color", "red");
                    } else {
                        $('#test' + i).css("color", "black");
                    }
                }
            }
        }


        //한글과 영문을 검사하는 함수(type은 원하는 case를 말한다.)
        function chkText(obj, type) {
            var source;
            switch (type) {
                case 1: //아이디 체크(첫글자 숫자안됨, 영문 + 숫자만 입력가능)
                    source = /^[a-zA-Z]{1}[A-Za-z0-9_]+$/;
                    break;
                case 2: //메일주소 체크
                    source = /^[\w\-]+@(?:(?:[\w\-]{2,}\.)+[a-zA-Z]{2,})$/;
                    break;
                case 3: //한글체크(이름)
                    source = /^[가-힣]+$/;
                    break;
                case 4: //한글 및 영문, 숫자 체크(닉네임)
                    source = /^[가-힣a-zA-Z0-9]+$/;
                    break;
                case 5:
                    source = /^([a-z]+):\/\/((?:[a-z\d\-]{2,}\.)+[a-z]{2,})(:\d{1,5})?(\/[^\?]*)?(\?.+)?$/i;
                    break;
                case 6: //비밀번호체크
                    source = /^[A-Za-z0-9]+$/;
                    break;
                case 7: //주민등록번호(숫자만입력 체크)
                    source = /^[0-9]+$/;
                    break;
                case 8: //한글 및 영문, 숫자, _
                    source = /^[가-힣a-zA-Z0-9_]+$/;
                    break;
                case 9: //한글 및 영문, 숫자, _
                    source = /^[가-힣a-zA-Z0-9Ⅰ-Ⅹ()_\.\-,\/]+$/;
                    break;
                case 10: //한글 및 영문, 숫자, -
                    source = /^[0-9\-]+$/;
                    break;
                case 11: //한글 및 영문
                    source = /^[가-힣a-zA-Z]+$/;
                    break;
                case 12: //영문
                    source = /^[a-zA-Z]+$/;
                    break;
            }
            var checked = source.test(obj);
            return checked;
        }
    </script>





글보기 페이지
테이블 셋팅을 위한 코드가 돌아가는 서버컨트롤이다. 서버컨트롤을 프로그램에서 호출 할 때 id를 사용하여 호출하기때문에 id는 정확하게 명시해야 한다. 
puzzleAnswer은  웹에서 입력받은 각 칸마다의 값들을, 모아 받아오기 위하여 runat="server"가 추가된 컨트롤(puzzleAnswer)을 말한다. puzzleAnswer 에 각각의 값을 모아두는 이유는, DB에 저장된 답과 비교하여 사용자가 풀어본 퍼즐 답과 일치하는지 비교하기 위해서다.
태그에 runat="server" 속성을 추가하면, 컨트롤이 서버컨트롤로 변환된다. 서버컨트롤이 되면 postback이 발생해도 값이 유지된다.
'정답확인'버튼의 onclick 이벤트가 발생하기 전에 OnClientClick으로 sendit()함수를 호출한다.
sendit() 함수에서 return 하는 값이 "true"가 아니면 OnClientClick 뒤에있는 onclick 이벤트가 실행되지 않는다.

PuzzleView.aspx_ 글보기(문제풀기) 
 <body>
<div id="contsTitleBox">
    <div class="contsTitleStr"><a href="/Default.aspx/">[낱말퀴즈목록]</a><a href="/PuzzleWrite.aspx">[낱말퀴즈등록]</a></div><br />
  
</div>
    <form id="form1" runat="server">
    <div id="tablePrint" runat="server" enableviewstate="false"></div>
    <p></p>
    <input type="hidden" id="puzzleAnswer" name="puzzleAnswer" runat="server" />
    
    <asp:Button ID="Button1" runat="server" Text="정답확인" OnClientClick="return sendit();" onclick="Button1_Click" />
    <asp:Label ID="result" runat="server" Text=""></asp:Label>
    <p></p>
    <table>
       <tr>
            <th width="400">가로문제</th>
            <th width="400">세로문제</th>
       </tr>
       <tr>
            <td align = "center"><asp:Label ID="widthContent" runat="server" Text=""></asp:Label></td>
            <td align = "center"><asp:Label ID="lenghtContent" runat="server" Text=""></asp:Label></td>
        </tr>
    </table>
    </form>
</body>
PuzzleView.aspx_javascript_sendit()
 <script type="text/javascript" src="/Scripts/jquery-1.4.1.min.js"></script>
    <script type="text/javascript" language="javascript">
        function sendit() {
            var lbl_puzzleAnswer = document.getElementById("<%=puzzleAnswer.ClientID %>");
            var test = $('.inputtest').length;
            var testStr = "";
            for (i = 0; i < test; i++) {
                testStr = testStr + $('#test' + i).val();
            }
            lbl_puzzleAnswer.value = testStr;
            //return false;
        }
    </script>




글목록 페이지
- 글 list는 등록된 글의 갯수만큼만(글이 없으면 글이 없다고 출력) 출력한다.
DB의 저장된 글을 웹에 뿌려주기 위하여 Repeater 사용한다.
<asp:Repeater>
     <HeaderTemplate>
     </HeaderTemplate>
     <ItemTemplate>
     </ItemTemplate>
     <FooterTemplate>
     </FooterTemplate>
</asp:Repeater>
Repeater안으로 들어가면, 실제로는 HeaderTemplate- 한번 ItemTemplate- DB저장된 갯수만큼 FooterTemplate- 한번 이러한 형태로 실행된다. Repeater는 DB의 저장된 문제의 갯수만큼 반복되는데, 정확하게 말하면 ItemTemplate반복된다고 생각하면 된다.
다른방법으로는 ItemTemplate만 Repeater로 감싸주는 방법이 있다. 하지만 나는 DB에 저장된 데이터가 없을 경우를 나타내기 위해서 HeaderTemplate, ItemTemplate, FooterTemplate 모두를 Repeater안에 감싸주고 프로그램에서 ItemTemplate만 실행되도록 제어한다.   

Default.aspx_ 글목록(List) 
 <body>
<div id="contsTitleBox">
    <div class="contsTitleStr"><a href="/PuzzleWrite.aspx">[낱말퀴즈등록]</a></div><br />
</div>
<div id="contsSubBox">
    <asp:Repeater ID="PuzzleListTable" runat="server" OnItemDataBound="PuzzleListTable_ItemDataBound" EnableViewState="false">
    <HeaderTemplate>
    <table>
    <tr>
        <th width="100">글번호</th>
        <th width="200">제목</th>
        <th width="130">등록일</th>
    </tr>
    </HeaderTemplate>
    <ItemTemplate>
    <tr>
        <td align="center"><%# Eval("idx")%></td>
        <td align="center"><asp:Label ID="title" runat="server" Text="" EnableViewState="false"></asp:Label></td>
        <td align="center"><%# Eval("regDate")%></td>
    </tr>
    </ItemTemplate>
    <FooterTemplate>
    <tr runat="server" id="_EmptyData" visible="true">
        <td align="center" height="300" colspan="7">등록된 낱말퀴즈가 없습니다.</td>
    </tr>
    </table>
    </FooterTemplate>
    </asp:Repeater>
    <div class="pagenavi" id="pagenavi" runat="server"></div>
</div>
</body>