순서
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 에 id 와 include태그의 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;
});
});
검색타입이 파라미터에 넘어간 모습
![](https://blog.kakaocdn.net/dn/cInfZa/btrDtioESyd/WhD4v7oE9hQhuQBGVZ2Pzk/img.png)
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태그 주소
};
= 결과는 같음.
'Spring boot | 쇼핑몰 만들기 | 어글리 마켓 > 홈페이지 만들기 | 고객,관리자' 카테고리의 다른 글
[레시피] 댓글 달기 기능 post (0) | 2022.06.13 |
---|---|
[레시피] 댓글 기능 Fetch API (0) | 2022.06.05 |
[레시피] 검색 기능 구현하기 (0) | 2022.05.17 |
[레시피] 게시판 페이지네이션 view (0) | 2022.05.17 |
[레시피] 게시판 페이지네이션 Criteria (0) | 2022.05.17 |