검색기능 넣기

list.jsp 폼 작업하기

폼 작업에서 name 부분들이 Criteria 클래스에 생성한 필드에 값을 받아오는 역할

pageNum과 amount도 사용해야 하기에 히든을 통해 value값으로 컨트롤러를 통해 PageDTO의 변경값을 받아온다

또한, PageDTO의 값은 Criteria에서 받아온다

name = 변수를 가져오고

value= 데이터를 가져온다

	<h3>게시판 글목록</h3>
	<form id="searchForm" action="/board/list" method="get">
		<select name="type" class="custom-select">
			<option value="">--</option>
			<option value="T">제목</option> <!-- T는 title -->
			<option value="C">내용</option>
			<option value="W">작성자</option>
			<option value="TC">제목 or 내용</option>
			<option value="TW">제목 or 작성자</option>
			<option value="TWC">제목 or 작성자 or 내용</option>
		</select>
		<input type="text" name="keyword">
		<input type="hidden" name="pageNum" value="${pageMaker.cri.pageNum }">
		<input type="hidden" name="amount" value="${pageMaker.cri.amount }">
		<button type="submit" class="btn btn-link">Search</button>
	</form>

xml에 작업

작업을 만들어서 중간에 삽입해주는 구문 만든다

이후 1)데이터 목록 쿼리와 2)테이블 데이터 개수에 넣어준다

<!-- 검색조건 쿼리. [제목 or 작성자]선택. value="TW" -->
<!-- typeArr : 파라미터타입의 Criteria클래스의 메서드를 가리킴. 검색종류(타입)의 값을 참조하게 됨 -->
<sql id="criteria">
    <trim prefix="(" suffix=") AND " prefixOverrides="OR">
        <foreach collection="typeArr" item="type">
            <trim prefix="OR">
                <choose>
                    <when test="type == 'T'.toString()">
                        title like '%' || #{keyword} || '%'
                    </when>
                    <when test="type == 'C'.toString()">
                        content like '%' || #{keyword} || '%'
                    </when>
                    <when test="type == 'W'.toString()">
                        writer like '%' || #{keyword} || '%'
                    </when>
                </choose>
            </trim>
        </foreach>
    </trim>
</sql>

<!-- 1)데이터 목록쿼리 -->
<select id="getListWithPaging" parameterType="com.demo.domain.Criteria" resultType="com.demo.domain.BoardVO">
    <![CDATA[
   SELECT RN, BNO, TITLE, CONTENT, WRITER, REGDATE
   FROM ( SELECT /*+ INDEX_DESC(TBL_BOARD PK_BOARD) */ ROWNUM RN, BNO, TITLE, CONTENT, WRITER, REGDATE
          FROM TBL_BOARD
          WHERE
  ]]>	       
    <include refid="criteria"></include>
    <![CDATA[
       ROWNUM <= #{pageNum} * #{amount}
  )
  WHERE RN > (#{pageNum}-1) * #{amount}
  ]]>
</select>

<!-- 2)테이블 데이터 개수 : 페이징구현사용 -->
<select id="getTotalCount" resultType="int">
    select count(*) from tbl_board where

    <include refid="criteria"></include>

    bno > 0
</select>

Mapper과 Service와 Impl, Controller까지 변경
	// Criteria 클래스에서 검색필드 3개 사용(type, keyword, typeArr)
	int getTotalCount(Criteria cri);

다시 list.jsp 작업

nav 바로 위에 form 작성을 해준다

id를 넣어서 위에 jquery에서 사용할 것이다

</ul>
<!-- 페이지 번호 클릭시 list주소로 보내는 파라미터 작업-->
<form id="actionForm" action="/board/list" mehthod="get">
    <input type="hidden" name="pageNum" value="${pageMaker.cri.pageNum }">
    <input type="hidden" name="amount" value="${pageMaker.cri.amount }">
    <input type="hidden" name="type" value="${pageMaker.cri.type }">
    <input type="hidden" name="keyword" value="${pageMaker.cri.keyword }">
</form>
</nav>

전에 작업했던 부분들은 첫 값이 들어온 이후 변경이 안되기 때문에 주석처리 하고 뒤에는 jquery 형식으로 작업한다

검색값인 type와 keyword의 값까지 가져와서 페이지를 이동시킨다

또한, 페이지 값이 클릭하면 변하도록 값을 가져와서 form에 넣는 작업을 한다

form의 아이디를 입력하고 값을 찾는 find를 입력 후 input에 있는 name에 있는 값 pageNum을 val()에 있는 값으로 변경해 링크를 걸어준다

<script>
    $(document).ready(function(){
        // 페이지 번호 클릭시 동작. 이전 1  2  3  4  5  다음
        $("li.page-item a.page-link").on("click", function(e){
            e.preventDefault(); // 태그의 기본득성을 제거. <a>태그의 링크기능을 제거

            // 검색기능 추가하여 아래구문 사용 안함  
            // let url = "list?pageNum=" + $(this).attr("href") + "&amount=10";
            // location.href = url;

            let actionForm = $("#actionForm"); // id가 actionForm인 form 참조

            // 현재 선택한 페이지 번호 변경작업
            actionForm.find("input[name='pageNum']").val($(this).attr("href"));

            actionForm.submit();

        });
    });
</script>

검색에 선택했던 것과 입력했던 키워드를 남도록 JSP 수정
<div class="container">
	<h3>게시판 글목록</h3>
	<form id="searchForm" action="/board/list" method="get">
		<select name="type">
			<option value="" <c:out value="${pageMaker.cri.type == null ? 'selected' : '' }"></c:out>>--</option>
			<option value="T" <c:out value="${pageMaker.cri.type eq 'T' ? 'selected' : '' }"></c:out>>제목</option>
			<option value="C" <c:out value="${pageMaker.cri.type eq 'C' ? 'selected' : '' }"></c:out>>내용</option>
			<option value="W" <c:out value="${pageMaker.cri.type eq 'W' ? 'selected' : '' }"></c:out>>작성자</option>
			<option value="TC" <c:out value="${pageMaker.cri.type eq 'TC' ? 'selected' : '' }"></c:out>>제목 or 내용</option>
			<option value="TW" <c:out value="${pageMaker.cri.type eq 'TW' ? 'selected' : '' }"></c:out>>제목 or 작성자</option>
			<option value="TWC" <c:out value="${pageMaker.cri.type eq 'TWC' ? 'selected' : '' }"></c:out>>제목 or 작성자 or 내용</option>
		</select>
		<input type="text" name="keyword" value="${pageMaker.cri.keyword }">
		<input type="hidden" name="pageNum" value="${pageMaker.cri.pageNum }">
		<input type="hidden" name="amount" value="${pageMaker.cri.amount }">
		<button type="submit" class="btn btn-link">Search</button>
	</form>
	
	<table class="table table-bordered">
  <thead>
    <tr>
      <th scope="col">글번호</th>
      <th scope="col">제목</th>
      <th scope="col">작성자</th>
      <th scope="col">등록일</th>
    </tr>
  </thead>
  <tbody>

수정하거나 다른 page로 이동했을 때에도 다 변수값 넣어주기

리스트를 뽑아오는 작업에서 a 태그에 class 값을 넣어주고 링크값 앞에 글번호를 제외하고 지워준다

<c:forEach items="${list }" var="board">
    <tr>
        <!-- BoardVO의 get메서드를 호출한다 -->
        <th scope="row"><c:out value="${board.bno }" /></th>
        <td><a class="move" href="${board.bno }"><c:out value="${board.title }" /> </a> </td>
        <td><c:out value="${board.writer }" /></td>
        <td><fmt:formatDate value="${board.regdate }" pattern="yyyy-MM-dd hh:mm" /></td>
    </tr>
</c:forEach>

그리고 자바스크립트에서 actionForm을 전역변수로 변경해 주고 위의 클래스 move에 대한 작업을 해준다

<script>
    $(document).ready(function(){

        // 전역변수로 변경
        let actionForm = $("#actionForm"); // id가 actionForm인 form 참조

        // 페이지 번호 클릭시 동작. 이전 1  2  3  4  5  다음
        $("li.page-item a.page-link").on("click", function(e){
            e.preventDefault(); // 태그의 기본득성을 제거. <a>태그의 링크기능을 제거

            // 검색기능 추가하여 아래구문 사용 안함  
            // let url = "list?pageNum=" + $(this).attr("href") + "&amount=10";
            // location.href = url;

            // 현재 선택한 페이지 번호 변경작업
            actionForm.find("input[name='pageNum']").val($(this).attr("href"));

            actionForm.submit();

        });

        // 목록에서 제목을 클릭시 동작.(페이징 파라미터, 검색 파라미터, 글번호)
        $("a.move").on("click", function(e){

            // $(this) : $(a.move) 선택자 중 클릭된 a 태그
            e.preventDefault();
            let bno = $(this).attr("href");

            actionForm.find("input[name='bno']").remove();
            
            // <form>태그의 자식으로 추가됨
            actionForm.append("<input type='hidden' name='bno' value='" + bno + "'>");
            actionForm.attr("action", "/board/get");

            actionForm.submit();

        });

    });
</script>

컨트롤러에도 Model 추가 작업
// @ModelAttribute("cri") Criteria cri : cri파라미터로 전송되어 온 값을 jsp로 전달하여, 사용하고자 할 경우에 작업
// Model model : 메서드 안에서 수동으로 데이터 작업하여, jsp에 전달하고자 할 경우.
@GetMapping(value= {"/get", "/modify"} )
public void get(@RequestParam("bno") Long bno, @ModelAttribute("cri") Criteria cri, Model model) {

    log.info("글번호 : " + bno);

    BoardVO board = service.get(bno);
    model.addAttribute("board", board);
    // 첫번째 "board"는 jsp 파일 내에서 서버를 불러올때 사용하는 변수
}

get.jsp 파일에 폼 만들어서 데이터 받아오기

주의점 - 폼은 list.jsp에서 가져와서 수정하는데 위에서 모델작업을 해서 pageMaker은 생략하고

글번호는 get.jsp파일에 있기 때문에 board.bno로 추가한다

<form id="operForm" action="/board/modify" method="get">
    <input type="hidden" name="bno" value="${board.bno }">
    <input type="hidden" name="pageNum" value="${cri.pageNum }">
    <input type="hidden" name="amount" value="${cri.amount }">
    <input type="hidden" name="type" value="${cri.type }">
    <input type="hidden" name="keyword" value="${cri.keyword }">
</form>

modify.jsp도 폼 넣기

기존에 있는 폼에 추가하고 get.jsp에서 똑같이 가져오면 기존에 board.bno가 중복이기 때문에 맨위에 input 빼준다

<input type="hidden" name="pageNum" value="${cri.pageNum }">
<input type="hidden" name="amount" value="${cri.amount }">
<input type="hidden" name="type" value="${cri.type }">
<input type="hidden" name="keyword" value="${cri.keyword }">

그리고 컨트롤러에서 PostMapping의 /modify도 변경해야 한다

@PostMapping("/modify")
public String modify(BoardVO vo, Criteria cri, RedirectAttributes rttr) {

    service.modify(vo);

    log.info("수정내용 : " + vo.toString());

    // /board/list 주소에 4개의 파라미터 정보가 추가되어진다
    rttr.addAttribute("pageNum", cri.getPageNum());
    rttr.addAttribute("amount", cri.getAmount());
    rttr.addAttribute("type", cri.getType());
    rttr.addAttribute("Keyword", cri.getKeyword());

    return "redirect:/board/list";

위처럼 해도 되지만 더 쉽게 Criteria 클래스에서 미리 만들어 놓는다

// 주소에 Criteria클래스 파라미터 추가작업
public String getListLink() {

    // 메서드 체이닝문법
    UriComponentsBuilder builder = UriComponentsBuilder.fromPath("")
        .queryParam("pageNum", this.pageNum)
        .queryParam("amount", this.amount)
        .queryParam("type", this.type)
        .queryParam("keyword", this.keyword);

    return builder.toUriString();
}

다시 컨트롤러에서 메서드 호출만 한다

	@PostMapping("/modify")
	public String modify(BoardVO vo, Criteria cri, /* RedirectAttributes rttr */) {
		
		service.modify(vo);
		
		log.info("수정내용 : " + vo.toString());
		
		// /board/list 주소에 4개의 파라미터 정보가 추가되어진다
//		rttr.addAttribute("pageNum", cri.getPageNum());
//		rttr.addAttribute("amount", cri.getAmount());
//		rttr.addAttribute("type", cri.getType());
//		rttr.addAttribute("Keyword", cri.getKeyword());
		
		return "redirect:/board/list" + cri.getListLink();
	}

댓글남기기