[회사일] new.jsp 태그파일 적용

code/new.jsp
<page:newpage label=”새 코드”>
    <f:select label=”코드종류” path=”cate” items=”${ref.codeCateList}” />
    <f:input label=”코드값” path=”code” />
    <f:input label=”코드명” path=”name” />
    <f:textarea label=”설명” path=”descr” />
</page:newpage>
member/new.jsp
<page:newpage label=”새 계정”>
    <f:input label=”로그인 ID” path=”loginId”/>
    <f:input label=”비밀번호” path=”password”/>
    <f:input label=”이름” path=”name”/>
    <f:input label=”이메일” path=”email”/>
</page:newpage>
new.jsp 페이지는 edit.jsp랑 비슷했으니까 간단간단 이제 view.jsp 페이지만 남았군요.

[회사일] mgt.jsp 파일에 태그 파일 적용

가운데는 그리드가 와야하고 오른쪽에는 검색 화면이 나와야하는 페이지. 이 페이지에 태그 파일을 적용해서…
<page:mgtpage label=”계정 관리”>
    <page:search label=”계정 검색”>
        <s:input label=”이름” path=”name” />
        <s:input label=”이메일” path=”email” />
    </page:search>
    <script type=”text/javascript”>
        $(function() {
            $(“#smdis-grid”).jqGrid({
                colNames:[‘id’, ‘아이디’, ‘이름’, ‘이메일’],
                colModel :[
                    {name:’id’, index:’id’, width:55, hidden:true},
                    {name:’loginId’, index:’loginId’, width:80},
                    {name:’name’, index:’name’, width:90},
                    {name:’email’, index:’email’, width:90},
                ]
            });
        });
    </script>
</page:mgtpage>
이런식으로 만들었습니다. 딱 봐도.. 검색 부분에 머머가 있구나.. 그리드에는 머머가 있구나가 보이니깐 이정도면 만족합니다. 태그 파일을 계속 써보니까 그 장점 중 하나가 태그에 좀 더 의미있는 이름을 줄 수 있다는 것이 있더라구요. 대신 단점으로는 이 태그 파일만 가지고 테스트 할 수 없다는게 좀 안타깝습니다. 계속해서 서버를 띄워둔 상태에서 릴로딩 해가면서 확인하고 있는데.. 아마 프리마커 같은 템플릿 엔진의 장점은 바로 테스트 용이성이 아닐까 싶습니다.
머 어쨋든 지금은 일단 JSP + 태그파일로 후딱 만들기로 했습니다. 
나중에 프리마커 + 매크로를 사용해서 대체해보는 방법도 생각해볼 수 있겠지만.. 머 나중에;
태그 파일을 분류해서 page는 페이지 구조와 관련된 태그를 만들고..
s는 검색에 사용할 폼 태그들을 만들고..
f는 수정이나 추가할 때 사용할 폼 태그들을 만들기로 했습니다.
 

[회사일] edit.jsp 화면에 태그 파일 적용하기

먼저 Code 도메인의 edit.jsp 코드를 보겠습니다.

<%@ page language=”java” contentType=”text/html; charset=UTF-8″ pageEncoding=”UTF-8″ %>
<%@ taglib prefix=”page” tagdir=”/WEB-INF/tags/page” %>
<%@ taglib prefix=”form” uri=”http://www.springframework.org/tags/form” %>
<page:page>
    <page:head/>
    <page:body>
        <div class=”ui-layout-center”>
            <h2 class=”smdis-pane-title” id=”smdis-grid-title”>
                <ul class=”smdis-left-icons”>
                    <li id=”smdis-save-button” class=”ui-state-default ui-corner-all” title=”저장”><span class=”ui-icon ui-icon-disk”></span></li>
                    <li id=”smdis-delete-button” class=”ui-state-default ui-corner-all” title=”삭제”><span class=”ui-icon ui-icon-trash”></span></li>
                    <li id=”smdis-reload-button” class=”ui-state-default ui-corner-all” title=”원래값으로”><span class=”ui-icon ui-icon-refresh”></span></li>
                </ul>
                <ul class=”smdis-right-icons”>
                    <li id=”smdis-list-button” class=”ui-state-default ui-corner-all” title=”목록으로”><span class=”ui-icon ui-icon-search”></span></li>
                    <li id=”smdis-back-button” class=”ui-state-default ui-corner-all” title=”뒤로”><span class=”ui-icon ui-icon-arrowreturnthick-1-w”></span></li>
                </ul>
                코드 수정
            </h2>
            <form:form commandName=”model” action=”/base/code/${model.id}” method=”PUT”>
                <p class=”ui-widget-content”><label>코드종류</label><form:select path=”cate” items=”${ref.codeCateList}” itemValue=”value” itemLabel=”descr” /><form:errors path=”cate” cssClass=”smdis-error-message”/></p>
                <p class=”ui-widget-content”><label>코드값</label><form:input path=”code”/><form:errors path=”code” cssClass=”smdis-error-message”/></p>
                <p class=”ui-widget-content”><label>코드명</label><form:input path=”name”/><form:errors path=”name” cssClass=”smdis-error-message”/></p>
                <p class=”ui-widget-content”><label>설명</label><form:textarea path=”descr”/></p>
            </form:form>
        </div>
        <%–//검색/정렬–%>
        <div class=”ui-layout-east”>
            <h2 class=”smdis-pane-title”>
                <ul class=”smdis-left-icons”>
                    <li id=”smdis-grid-apply” class=”ui-state-default ui-corner-all” title=”적용”><span class=”ui-icon ui-icon-arrowthickstop-1-w”></span></li>
                </ul>
                <ul class=”smdis-right-icons”>
                    <li class=”ui-state-default ui-corner-all” title=”적용하고 닫기”><span class=”ui-icon ui-icon-arrowthickstop-1-e”></span></li>
                </ul>
                검색
            </h2>
        </div>
    <script type=”text/javascript”>
        $(function() {
            $(“button”).button();
            $(“#smdis-save-button”).click(function(){
                var result = confirm(“저장 하시겠습니까?”);
                if(!result) return;
                $(“form input[name=’_method’]”).attr(“value”, “PUT”);
                $(“form”).submit();
            });
            $(“#smdis-delete-button”).click(function(){
                var result = confirm(“삭제 하시겠습니까?”);
                if(!result) return;
                
                $(“form input[name=’_method’]”).attr(“value”, “DELETE”);
                $(“form”).submit();
            });
            $(“#smdis-reload-button”).click(function(){
                var result = confirm(“변경 사항을 취소 하시겠습니까?”);
                if(!result) return;
                $(document).attr(“location”, ‘/base/code/${model.id}/form’);
            });
            $(“#smdis-back-button”).click(function(){
                $(document).attr(“location”, ‘/base/code/${model.id}’);
            });
            $(“#smdis-list-button”).click(function(){
                $(document).attr(“location”, ‘/base/code/mgt’);    
            });
        });
    </script>
    </page:body>
</page:page>
일부는 page라는 태그파일을 적용해서 코드를 많이 줄여놨습니다. 그래도 너무 길고.. Member의 edit.jsp 파일을 만들 때 손대는 곳은 굵은 글씨 밖에 없습니다. 신경쓸 곳만 신경쓰게 만들고 나머진 신경쓰고 싶지도 않고 보고 싶지도 않습니다. 그리고 위와 같은 코드가 여러 JSP에 중복되면.. 결국 자바 중복 코드랑 다를께 없습니다. 화면 코드에서도 중복을 제거해야 합니다.
Member 도메인의 edit.jsp 파일은 결국 다음과 같이 바꼈습니다.
<%@ page language=”java” contentType=”text/html; charset=UTF-8″ pageEncoding=”UTF-8″ %>
<%@ taglib prefix=”page” tagdir=”/WEB-INF/tags/page” %>
<%@ taglib prefix=”osaf” tagdir=”/WEB-INF/tags/osaf” %>
<%@ taglib prefix=”form” uri=”http://www.springframework.org/tags/form” %>
<page:page>
    <page:head/>
    <page:body>
        <page:edit label=”계정 수정”>
            <osaf:input label=”로그인ID” path=”loginId”/>
            <osaf:input label=”비밀번호” path=”password”/>
            <osaf:input label=”이름” path=”name”/>
            <osaf:input label=”이메일” path=”email”/>
        </page:edit>
        <page:searchWithoutButtons />
    </page:body>
</page:page>
정말 이게 전부입니다. 잡습 코드도 잡습이 적용될 코드가 들어있는 태그 파일로 넣어놨습니다. Code의 edit.jsp 파일에도 태그 파일을 적용하면..
<%@ page language=”java” contentType=”text/html; charset=UTF-8″ pageEncoding=”UTF-8″ %>
<%@ taglib prefix=”page” tagdir=”/WEB-INF/tags/page” %>
<%@ taglib prefix=”osaf” tagdir=”/WEB-INF/tags/osaf” %>
<%@ taglib prefix=”form” uri=”http://www.springframework.org/tags/form” %>
<page:page>
    <page:head/>
    <page:body>
        <page:edit label=”코드 수정”>
            <osaf:select label=”코드종류” path=”cate” items=”${ref.codeCateList}” itemValue=”value” itemLabel=”descr” />
            <osaf:input label=”코드값” path=”code”/>
            <osaf:input label=”코드명” path=”name”/>
            <osaf:textarea label=”설명” path=”descr”/>
        </page:edit>
        <page:searchWithoutButtons />
    </page:body>
</page:page>
이렇게 됩니다. 사실 저기서 위아래 세줄 정도도 관심 대상이 아니라서 page:editpage 같은 태그 파일을 만들어 줄일 수도 있습니다.
<%@ page language=”java” contentType=”text/html; charset=UTF-8″ pageEncoding=”UTF-8″ %>
<%@ taglib prefix=”page” tagdir=”/WEB-INF/tags/page” %>
<%@ taglib prefix=”osaf” tagdir=”/WEB-INF/tags/osaf” %>
<%@ taglib prefix=”form” uri=”http://www.springframework.org/tags/form” %>
<page:editpage label=”코드 수정”>
    <osaf:select label=”코드종류” path=”cate” items=”${ref.codeCateList}” itemValue=”value” itemLabel=”descr” />
    <osaf:input label=”코드값” path=”code”/>
    <osaf:input label=”코드명” path=”name”/>
    <osaf:textarea label=”설명” path=”descr”/>
</page:editpage>
좋아 좋아!!! 이제부터는 이렇게 딱 다섯줄만 코딩하면…
이런 화면을 만들 수 있는 겁니다.
이대로 끝내면 아쉬우니까 태그파일 코드 몇개만 공개하겠습니다.
WEB-INF/tags/page/editpage.tag
<%@ tag pageEncoding=”utf-8″ %>
<%@ taglib prefix=”page” tagdir=”/WEB-INF/tags/page” %>
<%@ taglib prefix=”form” uri=”http://www.springframework.org/tags/form” %>
<%@ attribute name=”label” required=”true”%>
<page:page>
    <page:head/>
    <page:body>
        <page:edit label=”${label}”>
            <jsp:doBody/>
        </page:edit>
        <page:searchWithoutButtons />
    </page:body>
</page:page>
WEB-INF/tags/osaf/select.tag
<%@ tag pageEncoding=”utf-8″ %>
<%@ taglib prefix=”page” tagdir=”/WEB-INF/tags/page” %>
<%@ taglib prefix=”form” uri=”http://www.springframework.org/tags/form” %>
<%@ attribute name=”label” required=”true”%>
<%@ attribute name=”path” required=”true”%>
<%@ attribute name=”items” type=”java.util.List” required=”true”%>
<%@ attribute name=”itemValue” required=”false”%>
<%@ attribute name=”itemLabel” required=”false”%>
<p class=”ui-widget-content”>
    <label>${label}</label>
    <form:select path=”${path}” items=”${items}” itemValue=”${itemValue}” itemLabel=”${itemLabel}” />
    <form:errors path=”${path}” cssClass=”smdis-error-message”/>
</p>

스프링 JSON view와 jQuery 이용하여 자동완성 기능 만들기 4

마무리로 태그 파일화 작업을 했습니다.

             <o:textwithac label=”이름” id=”name” size=”20″ maxlength=”30″
                 url=”/ajax/user/names.do” model=”users” width=”200″ selectFirst=”true” />

이런 태그와..

<script type=”text/javascript”>
function formatItem(row, i, total){
    return row[1] + ” ” + row[2];
}
function formatResult(row){
    return row[1];
}
function result(event, row, formatted){
    if (row){
        $(“#namedetail”).text(row[0] + ” ” + row[2]);
    }
}
</script>

자바스크립트 함수 세 개로 자동완성 기능을 사용할 수 있습니다.

속성 중에서

url=”/ajax/user/names.do” model=”users” width=”200″ selectFirst=”true”

이 녀석들이 자동완성과 관련된 속성들이며..

formatItem은 자동완성 목록을 어떤 형태로 보여줄지 코드를 작성해주면 되는데, 이 때 row는 현재 데이터 row이고, i는 인덱스, total은 총 갯수 입니다.

formatResult는 자동완성 목록에서 선택했을 때 text input 박스에 최종적으로 입력할 값을 return하도록 합니다.

마지막으로 result는 자동완성 목록을 선택했을 때 후 처리 이벤트 같은 것으로, result 타입의 이벤트와, 선택한 데이터 row, 그리고 formatResult에서 input 필드에 입력되도록 포맷팅한 값입니다. 이 녀석들을 이용해서 적당하게 코딩해주면 되겠습니다. 예제에서는 namedetila이라는 엘리먼트에 부가정보를 기입해주었습니다.

오늘 하루 타일즈(Tiles)에 낚였나보다~

성윤이랑 정말 신나게 가지고 놀았는데, 집에 갈 때 쯤이 다 되서 생각해 보건데..

매번 페이지를 추가할 때 마다 설정을 추가해야 한다는 건 정말 못 할 짓이다. 하루 종일 성윤이랑 씨름하며 개발중인 봄싹 사이트에 적용해 보았다.

못 할 짓이다.

안그래도 하면서 성윤이한테 이런 얘길 했었다.

    <!– main page  –>
    <definition name=”index” extends=”.root”>
        <put-attribute name=”content” value=”/jsp/index.jsp” />
    </definition>

    <definition name=”login” extends=”.root”>
        <put-attribute name=”content” value=”/jsp/login/login.jsp” />
    </definition>

    <!– member page  –>
    <definition name=”member/list” extends=”.root”>
        <put-attribute name=”content” value=”/jsp/member/list.jsp” />
    </definition>

    <definition name=”member/add” extends=”.empty”>
        <put-attribute name=”content” value=”/jsp/member/add.jsp” />
    </definition>

    <definition name=”member/view” extends=”.empty”>
        <put-attribute name=”content” value=”/jsp/member/view.jsp” />
    </definition>

    <definition name=”member/update” extends=”.empty”>
        <put-attribute name=”content” value=”/jsp/member/update.jsp” />
    </definition>

이런 식으로 계속 설정하는 건 정말 안 되겠다 싶어서, definition의 name 속성에 넣는 값이랑 put-attrubute의 value 속성에 넣는 값들이 비슷해 보이니까 저런걸 CoC 적용해서 자동으로 할 수 있게 패치를 만들어 볼까? 하는 얘길했었다.

그러나…

못 할 짓이고, 안 해도 될 것 같다. 하루 종일 공부했는데 허탈한 기분이 들지만..

사부님이 such is life 란다. ㅋㅋ

내일은 태그파일을 적용해봐야겠다.