gi_dor

FAQ 게시판 만들기 - 타입 선택시 해당 타입의 글만 보이게 하기 본문

First/Spring

FAQ 게시판 만들기 - 타입 선택시 해당 타입의 글만 보이게 하기

기돌 2023. 7. 11. 16:26
728x90

상단에 타입 선택시 해당하는 타입의 글만 보이게.

 

원하는 결과 : 타입선택시 해당 타입의 글만 보여주기
                     예를 들면 회원 타입 선택시 DB에서 faqTp가 10 인 모든글만 보여주게 하고싶음


해결방법 1: faqTp 로 동적으로 분류 해서 가져오기 - mapper도 따로 만들었는데 다른 사람한테 물어보니  
                 ajax ?를 써야한다고함 .. 포기

해결방법 2 : JS 코드로  타입 선택해서 해당 타입만 보여주고 다른 타입의 글들은 숨김처리하기

문제점  : JS로 하긴 했는데  타입 선택하면 현재 보고있는 1페이지에서 필터링 해서 보여 주기 때문에 DB에 있는
             모든글에서 필터링 해서 보여주지 않고있음 - 1페이지에서 선택한 타입의 글만 보임

해결방법 3 :  SearchCondition에 1페이지당 PageSize가 10으로 잡혀있음 이걸 만약 없애고 전체 글을 한페이지에
                    전부 보여준후 선택된 타입만 보이고 그외 타입은 숨김 - FAQ 게시판이라 글이 적어서 다행이지
                    자유 게시판이었으면 감당 안될,...

 


 

변경 전

 

faqList.jsp

<div class="content-mini right-case" id="ux_page_list">
  <form id="frm_search" action= "<c:url value="/faq/faqList"/>">


    <h3 class="title-t ty3 mb-30">자주 묻는 질문</h3>

          <div class="input etc-ty4 w-full">
                <input type="text" id="faqSearchText" name="keyword" class="inp" placeholder="궁금하신 내용을 입력해 주세요." value="${ph.sc.keyword}">

                <button type="submit" class="btn icon search big">
                  <span><i class="fa fa-search"></i></span>
                </button>
          </div>    
   		 <input class="faqType-small" type="button" name="faqTp" key = "00" value="전체">
        <input class="faqType-small" type="button" name="faqTp"  key = "10" value="회원">
        <input class="faqType-small" type="button" name="faqTp" key = "20" value="배송">
        <input class="faqType-small" type="button" name="faqTp" key = "30" value="주문 / 결제">
        <input class="faqType-small" type="button" name="faqTp" key = "40" value="교환 / 반품">
        <input class="faqType-small" type="button" name="faqTp" key = "50" value="이벤트">
        <input class="faqType-small" type="button" name="faqTp" key = "60" value="취소 / 환불">
        <input class="faqType-small" type="button" name="faqTp" key = "70" value="이용 안내">
        <input class="faqType-small" type="button" name="faqTp" key = "80" value="쿠폰 / 포인트">

<div class="board_list">
        <div class="slide-wrap slide-ty2">
            <c:forEach var="faqDto" items="${list}">
                <div class="slide-title">
                    <button type="button" class="slide-trg" faqTp="${faqDto.faqTp}" faqNo="${faqDto.faqNo}">
                        <em>Q.</em>
                        <strong>[ ${faqDto.faqTp} ]  ${faqDto.title}</strong>
                    </button>
                </div>

                <div class="slide-cont">
                    <div class="inner">
                        <div class="answer">
                            <em class="ia">A.</em>
                            <div class="cont">${faqDto.content}</div>
                        </div>
                    </div>
                </div>
            </c:forEach>
        </div>
    </div>
  
    
    // 페이징 핸들러 <<  < 1 2 3 4 6 7 8 9 10 > >>
    <div id="devPageWrap">
        <div class="wrap-pagination">
            <c:if test="${ph.totalCnt==null || ph.totalCnt==0}">
                <div> 게시물이 없습니다.</div>
            </c:if>

            <c:if test="${ph.totalCnt!=null && ph.totalCnt!=0}">

                <c:if test="${ph.showFirst}">
                    <a class="page"
                       href="<c:url value='/faq/faqList${pg.sc.getQueryString(ph.beginPage)}'/>">&lt;&lt;</a>
                </c:if>

                <c:if test="${ph.showPrev}">
                    <a class="page"
                       href="<c:url value='/faq/faqList${ph.sc.getQueryString(ph.beginPage-1)}'/>">&lt;</a>
                </c:if>

                <c:forEach var="i" begin="${ph.beginPage}" end="${ph.endPage}">
                    <a class="page ${i==ph.sc.page? "paging-active" : ""}"
                       href="<c:url value='/faq/faqList${ph.sc.getQueryString(i)}'/>">${i}</a>
                </c:forEach>

                <c:if test="${ph.showNext}">
                    <a class="page" href="<c:url value='/faq/faqList${ph.sc.getQueryString(ph.endPage+1)}'/>">&gt;</a>
                </c:if>

                <c:if test="${ph.showLast}">
                    <a class="page"
                       href="<c:url value='/faq/faqList${ph.sc.getQueryString(ph.totalPage)}'/>">&gt;&gt;</a>
                </c:if>

            </c:if>



    </div>
        </div>

 

DB

Controller

@GetMapping("/faqList")
    public String list( SearchCondition sc, Model m) {

//        if (!loginCheck(request))
//            return "redirect:/login/login?toURL=" + request.getRequestURL();  // 로그인을 안했으면 로그인 화면으로 이동
        try {
            int totalCnt = faqService.getSearchResultCnt(sc);
            m.addAttribute("totalCnt", totalCnt);

            PageHandler pageHandler = new PageHandler(totalCnt, sc);

            // 현재 페이지에서 해당 우형의 FAQ만 필터
            List<FaqDTO> list = faqService.getSearchResultPage(sc);


            // list에 제대로 담겨서 넘오올지 Test
            System.out.println("Faqlist = " + list);

            m.addAttribute("list", list);
            m.addAttribute("ph", pageHandler);
            Instant startOfToday = LocalDate.now().atStartOfDay(ZoneId.systemDefault()).toInstant();
            m.addAttribute("startOfToday", startOfToday.toEpochMilli());
            m.addAttribute("sc",sc);
//           m.addAttribute("page",page);
//           m.addAttribute("pageSize",pageSize);

        } catch (Exception e) {
            e.printStackTrace();
            m.addAttribute("msg", "LIST_ERR");
            m.addAttribute("totalCnt", 0);
        }

        return ViewPath.FOS_MYPAGE +"faqList";

    }

 

SearchCondition

package com.teamProject.syusyu.domain.cs;

import org.springframework.web.util.UriComponentsBuilder;

public class SearchCondition {  // 페이징에 필요한 클래스
    private Integer page = 1;   // 페이지
    private Integer pageSize = 10; // 한번에 보여줄 게시물의 갯수
    //    private Integer offset = 0;
    private String keyword = ""; // 검색어
    private String option = "";  // 검색 종류


    public SearchCondition(){}

    public SearchCondition(Integer page, Integer pageSize) {
        this.page = page;
        this.pageSize = pageSize;
    }

    public SearchCondition(Integer page, Integer pageSize, String keyword, String option) {
        this.page = page;
        this.pageSize = pageSize;
        this.keyword = keyword;
        this.option = option;
    }

    public String getQueryString(){
        return getQueryString(page);
    }


    public String getQueryString(Integer page) {
        //page?=1&pageSize=10&option=T&keyword="title"
        return UriComponentsBuilder.newInstance()
                .queryParam("page", page)
                .queryParam("pageSize", pageSize)
                .queryParam("option", option)
                .queryParam("keyword", keyword)
                .build().toString();

    }


    public Integer getPage() {
        return page;
    }

    public void setPage(Integer page) {
        this.page = page;
    }

    public Integer getPageSize() {
        return pageSize;
    }

    public void setPageSize(Integer pageSize) {
        this.pageSize = pageSize;
    }

    public Integer getOffset() {
        return (page - 1) * pageSize;
    }

//    public void setOffset(Integer offset) {
//        this.offset = offset;
//    }

    public String getKeyword() {
        return keyword;
    }

    public void setKeyword(String keyword) {
        this.keyword = keyword;
    }

    public String getOption() {
        return option;
    }

    public void setOption(String option) {
        this.option = option;
    }

    @Override
    public String toString() {
        return "SearchCondition{" +
                "page=" + page +
                ", pageSize=" + pageSize +
                ", offset=" + getOffset() +
                ", keyword='" + keyword + '\'' +
                ", option='" + option + '\'' +
                '}';
    }


}

 


 

변경 

 

변경해야할 항목 :
faqList.jsp - JS추가 , 페이징 삭제 , 검색바 키워드
Controller - list() 변경 
SearchCondition - FaqSearchCondition 새로 생성
Mapper -  내용변경


JS추가 , 페이징 삭제, 검색바 키워드

 <h3 class="title-t ty3 mb-30">자주 묻는 질문</h3>

          <div class="input etc-ty4 w-full">
                <input type="text" id="faqSearchText" name="keyword" class="inp" placeholder="궁금하신 내용을 입력해 주세요." value="${ph.fsc.keyword}">

                <button type="submit" class="btn icon search big">
                  <span><i class="fa fa-search"></i></span>
                </button>
          </div>

 


<input type="text" id="faqSearchText" name="keyword" class="inp" placeholder="궁금하신 내용을 입력해 주세요." value="${fsc.keyword}">

 

  <script>
      const faqTpButtons = document.querySelectorAll(".faqType-small");
      faqTpButtons.forEach(button => {
          button.addEventListener("click", function(event) {
              event.preventDefault();

              // 클릭한 FAQ 타입 값 가져오기
              const faqType = this.getAttribute("key");

              // 전체 페이지에서 FAQ 타입 필터링
              filterFAQs(faqType);
          });
      });

      // FAQ 필터링 함수
      function filterFAQs(faqType) {
          const faqItems = document.querySelectorAll(".slide-title");
          faqItems.forEach(item => {
              const faqTp = item.querySelector(".slide-trg").getAttribute("faqTp");

              if (faqType === "00" || faqTp === faqType) {
                  item.style.display = "block"; // 보여줄 FAQ
              } else {
                  item.style.display = "none"; // 숨김처리 FAQ
              }
          });
      }

      // 첫화면 전체 FAQ  보여주기
      filterFAQs("00");
    </script>

Controller - list() 변경

@Controller
@RequestMapping("/faq")
public class FaqController {

    @Autowired
    FaqService faqService;

  @GetMapping("/faqList")
    public String list(Model m, FaqSearchCondition fsc) {
        try {
            List<FaqDTO> list = faqService.getSearchResultPage(fsc); // 검색 결과 가져오기

            // list에 제대로 담겨서 넘어왔는지 테스트
            System.out.println("Faqlist = " + list);

            m.addAttribute("list", list);
            Instant startOfToday = LocalDate.now().atStartOfDay(ZoneId.systemDefault()).toInstant();
            m.addAttribute("startOfToday", startOfToday.toEpochMilli());
            m.addAttribute("sc", fsc);
        } catch (Exception e) {
            e.printStackTrace();
            m.addAttribute("msg", "LIST_ERR");
            m.addAttribute("totalCnt", 0);
        }

        return ViewPath.FOS_MYPAGE + "faqList";
    }
}

FaqSearchCondition 생성

public class FaqSearchCondition { 

	// 검색바에서 사용해야함
    private String keyword = ""; // 검색어
    private String option = "";  // 검색 종류
	
    // 기존 Integer Page , PageSize 사용 안할꺼니 삭제 


    public FaqSearchCondition(){}


    public FaqSearchCondition( String keyword, String option) {
        this.keyword = keyword;
        this.option = option;
    }

    public String getKeyword() {
        return keyword;
    }

    public void setKeyword(String keyword) {
        this.keyword = keyword;
    }

    public String getOption() {
        return option;
    }

    public void setOption(String option) {
        this.option = option;
    }

    @Override
    public String toString() {
        return "FaqSearchCondition{" +
                "keyword='" + keyword + '\'' +
                ", option='" + option + '\'' +
                '}';
    }


}

 


Mapper - 변경

  <sql id="searchConditionFaq">
                AND (TITLE LIKE CONCAT('%', #{keyword}, '%')
                OR CONTENT LIKE CONCAT('%', #{keyword}, '%'))
    </sql>


    <select id="searchSelectPageFaq" parameterType="FaqSearchCondition" resultType="FaqDTO">
        SELECT FAQ_NO , FAQ_TP , TITLE , CONTENT ,REGR_ID ,REG_DTTM
        FROM faq
        WHERE TRUE
        <include refid="searchConditionFaq" />
        ORDER BY REG_DTTM DESC, FAQ_NO DESC
    </select>

@GetMapping("/faqList")
public String list(Model model) {
    try {
        List<FaqDTO> list = faqService.getList(); // 모든 FAQ 목록 가져오기

        // list에 제대로 담겨서 넘어왔는지 테스트
        System.out.println("Faqlist = " + list);

        model.addAttribute("list", list);
        Instant startOfToday = LocalDate.now().atStartOfDay(ZoneId.systemDefault()).toInstant();
        model.addAttribute("startOfToday", startOfToday.toEpochMilli());

    } catch (Exception e) {
        e.printStackTrace();
        model.addAttribute("msg", "LIST_ERR");
        model.addAttribute("totalCnt", 0);
    }

    return ViewPath.FOS_MYPAGE + "faqList";
}

컨트롤러 변경시 페이징 처리 안하고 한번에 보려고 이렇게 변경하다가
검색기능 망가지고
검색기능 고치려고 FaqSearchCondition 새로 만들고
Mapper 수정하고
jsp 수정하고....

단순하게 컨트롤러 메서드나 조금 바꾸면 될줄 알고 30분이면 끝나겠네 했는데
연쇄적으로 에러가 터져서 검색하고 강의찾아보고 수정하고 삭제하고  기능 하나 바꾸려다가 3~4시간은
훌쩍 지나가 버렸다.

 


마지막 테스트


1. 검색기능 

 

2. 타입 체크


 

728x90