순서

1. Criteria 

2. RecipeMapper.xml

3. view 

 

 

 

1. [ Criteria ] 

type, [] type Arr  변수 추가하고, toString도 다시 설정하기

/* 검색 타입 */
private String type;

/* 검색 타입 배열 */
private String[] typeArr;


/* getter setter*/
public String getType() {
  return type;
}

public void setType(String type) {
  this.type = type;
  this.typeArr = type.split("");   //한 문자씩 끊어서 배열로 만듬
}

public String[] getTypeArr() {
  return typeArr;
}

public void setTypeArr(String[] typeArr) {
  this.typeArr = typeArr;
}

setType 에 입력된 문자열을 저장하고

this.typeArr = type.split("");  →   타입배열에 문자열을 분리하고 배열로 저장

ex)  타입이 "TC" => 배열 {"T", "C"} 

           TC (제목+내용)

 

 왜 setType 에 적느냐

= 검색할 타입만 설정되면 typeArr은 자동으로 생성이라 

 

 

 

2.  [ RecipeMapper.xml ]   

쿼리문 작성 

<!-- 검색 조건문 where절을 각각의 type이 있으면 추가해준다. -->
    <sql id="criteria">
        <trim prefix="where (" suffix=")" prefixOverrides="OR">
            <foreach collection="typeArr" item="type">
                <trim prefix="OR">
                    <choose>
                        <when test="type == 'T'.toString()">
                            title like concat('%',#{keyword},'%') 
                        </when>
                        <when test="type == 'C'.toString()">
                            content like concat('%',#{keyword},'%') 
                        </when>
                        <when test="type == 'W'.toString()">
                            writer like concat('%',#{keyword},'%' )
                        </when>
                    </choose>
                </trim>
            </foreach>
        </trim>
    </sql>

where절인 <when>태그에 각 type 이 T, C, W 문자열이 있으면 추가가 가능. (T+C, T+W, + T+C+W ...)

 

 

"T"(제목), "C"(내용), "W"(작성자), 

 

- collection="typeArr" 타입을 배열로

- prefix="OR" 는 두개가 검색이 가능하다는 것. 

TC = { "T" , "C" }

TW = { "T" , "W" }

TCW = { "T" ,  "C" , "W" }

 


게시물을 검색하니까

게시물 목록 쿼리에서 검색방법 추가해주기  →  게시물 총 개수에도 똑같이 추가

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

위에서 sql문 작성했던 RecipeMapper.xml 에 idinclude태그의 refid 같게해주기!

<sql id="criteria"> = <include refid="criteria">

= 검색타입이 추가

 

 


3. view

<div class="d-flex justify-content-center mt-2">
    <!-- 검색기능 -->
    <div class="input-group input-group-static me-3" style="width: 8em">
        <label for="select1" class="ms-0">검색방법</label>
        <select class="form-control" id="searchType">
            <!-- <option value="" th:selected="${pmk.criteria.type} == ''"></option> -->
            <option value="T" th:selected="${pmk.criteria.type} == 'T'">제목</option>
            <option value="C" th:selected="${pmk.criteria.type} == 'C'">내용</option>
            <option value="W" th:selected="${pmk.criteria.type} == 'W'">작성자</option>
            <option value="TC" th:selected="${pmk.criteria.type} == 'TC'">제목 + 내용</option>
            <option value="TW" th:selected="${pmk.criteria.type} == 'TW'">제목 + 작성자</option>
            <option value="TCW" th:selected="${pmk.criteria.type} == 'TCW'">제목 + 내용 + 작성자</option>
        </select>
    </div>

      <div class="w-md-25 w-sm-50 input-group input-group-outline is-filled">
        <input type="text" id="searchKeyword" th:value="${pmk.criteria.keyword}" class="form-control
           placeholder="search here.." />
        <button id="searchButton" class="btn btn-primary mb-0">검색</button>
    </div>
</div>

th:selected="${pmk.criteria.type} == 'T'"  →   검색타입을 변경할때 유지되는것
th:value="${pmk.criteria.keyword}"  →  검색한 키워드가 유지되는

 

 

 

 

+ 검색버튼 눌렀을때 js로 설정해준곳에 type 추가하기

 

1. 검색버튼 눌렀을때 검색타입도 파라미터에 넘어가도록

 

2. 페이지네이션 태그들 누를때 검색타입도 넘겨지도록 

 

3. 게시글에서 목록으로 갈때, 수정취소할때 검색타입 추가

 

 

 

 

 

1. 검색버튼 눌렀을때

2. 페이지네이션 태그들 누를때 

[ list.html ]

const searchKeyword = document.getElementById('searchKeyword'); //검색창의 input 값내용
const searchButton = document.getElementById('searchButton'); //검색버튼
const searchType = document.getElementById('searchType');

/* 검색버튼 눌렀을때 (이벤트 'click') 키워드를 url에 추가해서 보내기 */
searchButton.addEventListener('click', function(){
    let keyword = ''; //키워드 변수 선언
    let 공백제거키워드 = searchKeyword.value.trim();
    let type = '';
    if(공백제거키워드) { //키워드가 있으면 &keyword=키워드
        keyword = '&keyword=' + 공백제거키워드; 
        type = '&type=' + searchType.value;   // T,W,C
    }
    location.href='/recipe/board/list?pageNum=1' + keyword + type

});

/* 페이지네이션 a태그들을 전부 Js 요청으로 바꾸기 (키워드 추가) */
const pageLinks = document.querySelectorAll('ul.pagination .page-link');
pageLinks.forEach(function(link){ //a태그가 한개씩 link로 들어감
    //각각의 a태그를 클릭 시 함수실행
    link.addEventListener('click', function (e) {
        e.preventDefault(); //a태그의 이동 요청이 취소됨. (검색후 페이지네이션 누를때 돌아가는거 방지)
        let keyword = ''; //키워드 변수 선언
        let 공백제거키워드 = searchKeyword.value.trim();
        let type = '';
        if (공백제거키워드) { //키워드가 있으면 &keyword=키워드
            keyword = '&keyword=' + 공백제거키워드;
            type = '&type=' + searchType.value;   // T,W,C
        }

        location.href = this.getAttribute('href') + keyword + type
    });
});

const getLinks = document.querySelectorAll('table .title');
getLinks.forEach(function(link){ //a태그가 한개씩 link로 들어감
    //각각의 a태그를 클릭 시 함수실행
    link.addEventListener('click',function(e){
        e.preventDefault(); //a태그의 이동 요청이 취소됨. (검색후 페이지네이션 누를때 돌아가는거 방지) 
        let keyword = ''; //키워드 변수 선언
        let 공백제거키워드 = searchKeyword.value.trim();
        let type = '';
        if (공백제거키워드) { //키워드가 있으면 &keyword=키워드
            keyword = '&keyword=' + 공백제거키워드;
            type = '&type=' + searchType.value;  // T,W,C
        }
        let pageNum = '[[${criteria.pageNum}]]'; //현재 페이지 active 의 a태그
        location.href= this.getAttribute('href') + keyword + '&pageNum=' + pageNum + type
    });
}); 

 

검색타입이 파라미터에 넘어간 모습

 

 

3. 게시글에서 목록으로 갈때 (검색타입 그대로)

[ get.html ] 

const links = document.querySelectorAll('a.page');  //주의! a태그 안의 class라서 붙여주기
links.forEach(function(link){ //a태그가 한개씩 link로 들어감
    //각각의 a태그를 클릭 시 함수실행
    link.addEventListener('click',function(e){
        e.preventDefault(); //a태그의 이동 요청이 취소됨. 
        let keyword = '[[${criteria.keyword}]]'; 
        let type = '[[${criteria.type}]]'
        if(keyword.trim()){
            keyword = '&keyword=' + keyword;
            type = '&type=' + type;
        }
        location.href= this.getAttribute('href') +  keyword + type
    });
}); 

 

3. 수정취소 할때 (검색타입 그대로)

[ modify.html ] 

<a th:href="@{/recipe/board/list} + '?pageNum=__${criteria.pageNum}__'" class="btn btn-lg btn-danger page">
     수정 취소
</a>

키워드는 밑에 js로 

<script>
// 수정취소 클릭시 검색타입, 키워드 그대로 돌아가게
const links = document.querySelectorAll('a.page');
links.forEach((link) => {
    link.addEventListener('click', function (e) {
        e.preventDefault();
        let keyword = '[[${criteria.keyword}]]';
        let type = '[[${criteria.type}]]';
        if (keyword.trim()) {
            keyword = '&keyword=' + keyword;
            type = '&type=' + type;
        }
        location.href = this.getAttribute('href') + keyword + type;
    });
});
</script>

 

'수정취소' 버튼 하나밖에 없어서  links.forEach((link) => {};  반복문 쓸 필요가 없...

을 줄 알았는데! 키워드랑 검색타입 처음으로 돌아간다??

그냥 써줬더니 키워드, 검색타입 그대로 유지된다.. 그냥 쓰자!

 

 

 

 


코드정리.

list.html 의 js부분에  function함수가 비슷해보이니 코드 정리를 해보자 

const pageLinks = document.querySelectorAll('ul.pagination .page-link');
pageLinks.forEach(function(link){ //a태그가 한개씩 link로 들어감
    //각각의 a태그를 클릭 시 함수실행
    link.addEventListener('click', function (e) {
        e.preventDefault(); //a태그의 이동 요청이 취소됨. (검색후 페이지네이션 누를때 돌아가는거 방지)
        let keyword = ''; //키워드 변수 선언
        let 공백제거키워드 = searchKeyword.value.trim();
        let type = '';
        if (공백제거키워드) { //키워드가 있으면 &keyword=키워드
            keyword = '&keyword=' + 공백제거키워드;
            type = '&type=' + searchType.value;   // T,W,C
        }

        location.href = this.getAttribute('href') + keyword + type; 
    });
});

const getLinks = document.querySelectorAll('table .title');
getLinks.forEach(function(link){ //a태그가 한개씩 link로 들어감
    //각각의 a태그를 클릭 시 함수실행
    link.addEventListener('click',function(e){
        e.preventDefault(); //a태그의 이동 요청이 취소됨. (검색후 페이지네이션 누를때 돌아가는거 방지) 
        let keyword = ''; //키워드 변수 선언
        let 공백제거키워드 = searchKeyword.value.trim();
        let type = '';
        if (공백제거키워드) { //키워드가 있으면 &keyword=키워드
            keyword = '&keyword=' + 공백제거키워드;
            type = '&type=' + searchType.value;  // T,W,C
        }
        let pageNum = '[[${criteria.pageNum}]]'; //현재 페이지 active 의 a태그
        location.href= this.getAttribute('href') + keyword + '&pageNum=' + pageNum + type; 
    });
}); 

 

function(e) 함수 안의 내용을 function pageController(e)  새로운 함수에 내용을 넣어서 코드정리해보자.

 

function(e) 자리에는 pageController 새로운 함수 이름만! 넣는다    ※ pageController(e) 하면 안됨.

 

 

새로운 함수 pageController 로 코드 정리하고

pageNum은 태그에 직접 추가하면 된다. 

<td class="align-middle text-center">
    <a class="title" th:href="@{/recipe/board/get(id=${board.id})}+'&pageNum=__${pmk.criteria.pageNum}__'">
        <span class="text-secondary text-xs" th:text="${board.title}"></span>
    </a>
</td>

 

정리.

const pageLinks = document.querySelectorAll('ul.pagination .page-link');
pageLinks.forEach(function(link){ //a태그가 한개씩 link로 들어감
    //각각의 a태그를 클릭 시 함수실행
    link.addEventListener('click', pageController);
}); 

const getLinks = document.querySelectorAll('table .title');
getLinks.forEach(function(link){ //a태그가 한개씩 link로 들어감
    //각각의 a태그를 클릭 시 함수실행
    link.addEventListener('click',pageController);
}); 

function pageController(e){
    e.preventDefault(); //a태그의 이동 요청이 취소됨. (검색후 페이지네이션 누를때 돌아가는거 방지) 
        let keyword = ''; //키워드 변수 선언
        let 공백제거키워드 = searchKeyword.value.trim();
        let type = '';
        if (공백제거키워드) { //키워드가 있으면 &keyword=키워드
            keyword = '&keyword=' + 공백제거키워드;
            type = '&type=' + searchType.value; //T,W,C
        }

        location.href = this.getAttribute('href') + keyword + type; //this는 클릭한 a태그 주소

};

= 결과는 같음.

 

 

 

반응형
LIST

+ Recent posts