DisplayTag에서 팝업 링크 달기

DisplayTag를 계속해서 사용해보니, 한계점들이 들어납니다. 역시 직접 사용해서 뭔가 만들어보기 전까진 모르는건가 봅니다. 암튼, 찾아보니 어떻게든 방법은 있길래 적용했습니다.

    <d:column title=”No”>
        <a href=”javascript:sendToUpdate(<c:out value=”${maingrid.id}” />)”>
            <%out.print(count++);%>
        </a>
    </d:column>

거의뭐.. displaytag가 해주는 일은 없습니다. 그냥 자바스크립트를 이용해서 팝업창 띄우기라고 글 제목을 바꿔야할지도 몰겠습니다.

<script type=”text/javascript”>
function sendToUpdate(selectedId) {
    popup(“update.do?id=” + selectedId + “&gridid=maingrid”, “maingridpopup”, 500, 600, “yes”, “yes”);
}

이제, 그리드 완성입니다. 태그 파일로 다듬고, 태그 파일 서술자 만들어서 url로 태그 파일 참조해서 사용할 수 있는지만 확인하면 OSAF 배포합니다. 이번 주를 목표로 합니다. 아자 아자 파이팅!!!!

DisplayTag 히든 컬럼(hidden column) 추가하기

캬오.. 간단하지 않네요. media 속성 값중에 “none”이라는 값을 지원해주면 좋을텐데, 이 값은 지원하지 않습니다. 이슈 트래커에 올리면 반영해주려나.. 흠..

방법은.. 일단 CSS에 hidden이라는 클래스 하나를 추가합니다.

.hidden {
    display: none;
}

그리고 컬럼의 class와 headerClass의 값을 hidden으로 설정해줍니다.

    <d:column property=”id” class=”hidden” headerClass=”hidden” />

끝~ 나중에 OSAF 태그 파일로 감싸서 좀 더 간단하게 이 기능을 제공할 수 있겠습니다. isHidden 이라는 속서을 추가해서 말이죠. 간단하게~ 명시적으로~

그리드 태그 파일 으윽.. 머리야~

사용자 삽입 이미지
현재 그리드에 스타일 적용과 데코레이터 사용법까지 확인을 했고, 뭘 해야 할지 잠시 정리해 봤습니다. 곰곰히..

1. 페이지 네비게이션 바 추가.(완료)
-> displaytag가 제공하는 네비게이션바도 있지만, 그건 이미 많은 양의 데이터를 세션에 집어넣고 그 중에서 페이징처리를 하는거기 때문에 별로입니다. 제대로 페이징을 하려면 서비스 단에서 제공하는 만큼의 데이터가 한 페이지 분량이 되고, 페이징 로직도 서비스단에서 제공하는 걸 이용해야 합니다.

2. id값을 히든 컬럼으로 추가.(완료)
-> 한 Row가 하나의 객체 정보를 보여주고 있고 그 중에 선택을 해서 삭제/수정 작업을 하려면 id를 물고 있어야합니다. 따라서 id 값은 테이블에 안 보이는 컬럼으로 추가되어 있어야합니다.

3. 순번 표시(완료)
-> id가 아닌, 컬럼 줄 수를 표시해야 합니다. 500개의 데이터 중에 해당 줄이 몇 번째 데이터에 해당하는지, 기본적으로 이 순서로 정렬해서 보여줄 필요가 있겠죠. 이 기능도 역시 서비스 단과 맞물려서 동작해야겠습니다. displaytag에서도 뭔가 제공해주겠지만, 그건 저 한 페이지 내용에 대한 순번일 뿐, 전체 데이터에 대한 순번은 서비스 단이 알고 있을테니 말이죠.

4. 정렬 기능(에러)
-> 각 컬럼 헤더에 정렬 단추를 달고, 해당 단추를 눌러서 정렬 할 수 있는 기능을 제공해야 합니다. 이 기능은 displaytag가 제공하기 때문에, 설정만 추가하면 됩니다.

5. 링크 기능
-> 어떤 줄을 더블클릭하면, 바로 수정 화면으로 이동하도록 설정하고 싶습니다. 이 기능은 displaytag가 제공하는 링크 기능을 이용하면 간단하게 될 듯 합니다.

6. 컬럼 데이터 포맷
-> 금액이나 날짜 데이터의 경우 포맷을 설정할 수 있는 기능을 displaytag가 제공합니다. 그 패턴을 좀 익혀서 정리해둬야 겠습니다.

7. 체크 박스
-> 그리드 맨 왼쪽에 체크 박스 컬럼을 만들어서 다중 선택을 지원합니다. 다중 선택으로 해당 객체의 id 값들의 배열을 특정 요청 매개변수로 넘겨줄 수 있다면, 그 뒤엔 여러가지 일들을 할 수 있겠죠.

이밖에도 그리드 편집/새로운 줄 추가 등 여러 기능이 있을 수 있겠지만.. 일단 저 위의 것들부터도 그닥 만만해 보이지 않습니다. 저것만 끝내면 OSAF 공개인데… ㅠ.ㅠ 파이팅 하자 파이팅 해..

updated today 6:00

DisplayTag 데코레이터 사용하기

참조 : http://displaytag.sourceforge.net/11/tut_decorators.html

어떻게 만드는지에 대한 설명은 없고 사용법만 나와있습니다. 에잉~ 어쩔 수 없이 Javadoc을 살펴봤습니다. 뭔가 인터페이스를 만들어 놓고 그걸 구현하게 해 뒀겠지.. 싶어서 찾아봤습니다.

올커니.. 너였구나. ColumnDecorator. 에엥; 왠걸 Deprecated 됐습니다. DisplaytagColumnDecorator 1.1부터는 이 인터페이스를 사용하라네요. 자세한건 귀찮아서 패~스.

구현해야 할 메소드는 딱 하나.

    public Object decorate(Object object, PageContext context, MediaTypeEnum typeEnum)
            throws DecoratorException {
    }

object로 넘어온 값을 원하는 형태로 저 안에서 변형시킨 다음에 넘겨주면 됩니다. 저는 인터페이스를 타입 구현체에서 구현하게 했습니다.

public class SexType extends AbstractType implements DisplaytagColumnDecorator {

    public static final int MALE = 10;
    public static final int FEMALE = 20;
   
    public SexType() {
        super(Arrays.asList(
            new Pair(MALE, “남성”),
            new Pair(FEMALE, “여성”)));
    }
   
    private static SexType sexType = new SexType();
   
    public static SexType getInstance(){
        return sexType;
    }

    @Override
    public Object decorate(Object object, PageContext context, MediaTypeEnum typeEnum)
            throws DecoratorException {
        return this.decode((Integer)object);
    }
   
}

이렇게 말이죠. 그럼 뷰에서는 저 데코레이터 인터페이스를 구현한 클래스 풀 패키지 경로를 포함한 이름으로 설정해주면.. 됩니다.

<d:table name=”list”>
    <d:column property=”name” />
    <d:column property=”loginId” />
    <d:column property=”sex” decorator=”org.opensprout.sample.model.enumeration.SexType” />
    <d:column property=”location” />
    <d:column property=”birthday” />
    <d:column property=”hobbies” />
</d:table>

흠.. 고민이 있는데, 저런 데코레이터를 지금처럼 특정 타입에 대한 데코레이터니까, 타입 클래스가 구현하는게 좋을지 아니면 별도의 클래스로 분리하는게 좋을지.. 잘 모르겠습니다. 또 고민이 있는데, 저 인터페이스가 jsp 인터페이스에 종속되어 있어서(PageContext), SexType이라는 클래스가 디스플레이 태그 API와 JSP API의 침략을 당한다는 것입니다. 이 부분이 상당히 껄끄러운데.. 어쩜 좋을지.. 고민이 됩니다.

어차피 decode()라는 메소드가 AbstractType에 존재한다는 건, 디코딩 역할을 하겠다는 것이고, 뷰에서도 디코딩 역할을 이 녀석이 책임지는 것이 그리 나쁘지 않을 것 같다는 판단하에 타입 클래스가 구현하게 했습니다. 훔~

아니면..

저렇게 데코레이터를 사용하지 않고 도메인 클래스에 getSexDecode()라는 메소드를 추가하고, 뷰에서는 sex가 아니라, property=”sexDecode” 라고 참조하는 방법도 있습니다.

단, 이 방법은 도메인 클래스의 역할이 역시 좀 이상해 집니다. 뷰에서 어떤 값을 보여주기 위해 디코딩하는 일이 도메인 클래스에 들어있는게, 그리 아름다워 보이지가 않아서 말이죠. 하지만, 이 방법을 쓰면 디스플레이 태그 API가 침범하지도 않고, 따라서 JSP API의 침범도 없습니다.

갈등이네요. (– ) ( –) 어찌하면 좋을꼬…

DisplayTag 링크 기능

참조 : http://displaytag.sourceforge.net/11/tut_links.html

<display:column property=”name” title=”이름” href=”detail.do” paramId=”id” paramProperty=”id” sortable=”true” />

이런식으로 지정해 주면 detail.do 로 링크가 생기며 이 링크로 객체의 id를 id라는 이름으로 넘겨 줍니다.

이것을 받아서 member 한명에 대한 정보를 뿌리는 controller를 만듭니다.
[#M_ more.. | less.. | public class MemberDetailController extends AbstractController{

   private MemberRepository memberRepository;

   @Override
   protected ModelAndView handleRequestInternal(HttpServletRequest request, HttpServletResponse response) throws Exception {

       Integer id = Integer.parseInt(request.getParameter(“id”));
       Member member = memberRepository.get(id);
       return new ModelAndView(“detail”, “member”, member);
   }

   public void setMemberRepository(MemberRepository memberRepository) {
       this.memberRepository = memberRepository;
   }
}_M#]id로 넘어온 id를 받은 뒤 그것을 가지고 member 객체를 가져오고 다시 member 객체를 detail이라는 view와 함꼐 ModelAndView 객체에 담아서 리턴합니다. 그럼 viewResolver에 의해서 detail.jsp를 찾아가게 될 것입니다.
[#M_ more.. | less.. | <jsp:root version=”1.2″ xmlns:jsp=”http://java.sun.com/JSP/Page”
    xmlns:display=”urn:jsptld:http://displaytag.sf.net”
    xmlns:c=”urn:jsptld:http://java.sun.com/jstl/core“>

    <jsp:directive.page contentType=”text/html; charset=UTF-8″ />
    <jsp:include page=”inc/header.jsp” flush=”true” />

    <h2><c:out value=”${member.name}”/>’s Information</h2>

    <table>
        <tr>
            <th>이름</th>
            <td><c:out value=”${member.name}”/></td>
        </tr>
        <tr>
            <th>Email</th>
            <td><c:out value=”${member.email}”/></td>
        </tr>
        <tr>
            <th>Phone</th>
            <td><c:out value=”${member.phone}”/></td>
        </tr>
        <tr>
            <th>Blog</th>
            <td><c:out value=”${member.blogAddress}”/></td>
        </tr>
        <tr>
            <th>MessengerId</th>
            <td><c:out value=”${member.messengerId}”/></td>
        </tr>
    </table>

    <jsp:include page=”inc/footer.jsp” flush=”true” />
</jsp:root>_M#]
JSTL을 사용하기 위해 taglib을 지정해 주고 이 페이지에 member객체가 넘어 왔을 테니깐 “${member.name}” 이런식으로 사용해주면 됩니다.

사용자 삽입 이미지
결과는..
사용자 삽입 이미지