현재 상황
각 카테고리에 맞게 버튼이 되어있고 카테고리를 클릭하고 검색 버튼을 누르면 그에 맞는 게시물이 아래에 렌더링되게 하고 싶다
여기서 특이사항은 카테고리 버튼은 여러개가 눌릴 수 있어야 한다는 것!
1. 첫 번째 방법
내가 생각한 첫번째 방법은 ajax를 이용해서 클릭된 카테고리 버튼의 배열을 저장하는 것이다.
list.html의 일부이다. id는 카테고리의 id로 지정하고, 클릭시 id를 파라미터로 넘겨주는 onClick 함수를 호출한다.
<!-- list.html의 script 일부 -->
<div class="gather-category">
<div th:each="category,index:${categoryList}">
<label><input type="button" name="category" class="btn btn-outline-info" th:value="${category.tagName}" th:id="${category.id}" onclick="onClick(this.id)"></label>
</div>
</div>
onClick 함수부분의 처리는 다음과 같다
<!-- list.html의 script 일부 -->
<script>
let arr=[];
function onClick(id) {
var button = document.getElementById(id);
button.classList.toggle('active');
var idx = arr.indexOf(id);
if(idx > -1) {
arr.splice(idx, 1);
} else {
arr.push(id);
}
}
$(document).on("click", "#searchBtn", function () {
$.ajax({
url: "/gathering/search",
type: "GET",
contentType: "application/json; charset=UTF-8",
dataType: "json",
data: {
"category": arr,
"classification": $("#classification option:selected").val(),
"searchKeyword" : $("#searchKeyword").val(),
},
success: function (data) {
//console.log(data.resultData);
arr = [];
if (data.result == true) {
alert("성공");
}
}
});
});
</script>
이렇게 arr이라는 배열을 선언하고 클릭시 파라미터로 받은 id를 arr에 넣어준다.
버튼이 bootstrap으로 꾸며져있어서 클릭효과를 주기 위해서 active를 토글하는 방식으로 배경색을 입혔고, arr 배열에 해당 id값이 들어가있으면 넘어가고, 없는 경우엔 배열에 넣어준다.
따라서 검색 버튼이 눌렸을때, ajax로 arr 배열을 “category”라는 값으로 보낸다!
요청을 받는 Controller 부분이다.
//GatheringListController.java
@GetMapping("/search")
public ModelAndView searchBoard(ModelAndView mav, @ModelAttribute GatheringListCriteria criteria){
mav.setViewName("jsonView");
System.out.println(criteria.toString());
List<GatheringListDetailDto> gatheringBoardList = gatheringService.listByCriteria(criteria);
for(GatheringListDetailDto dto : gatheringBoardList) {
System.out.println(dto.toString());
}
mav.addObject("gatheringList", gatheringBoardList);
return mav;
}
로그를 보니 내가 의도했던 대로 category 값이 List<Integer>의 형태로 잘 들어가있음을 확인할 수 있다.
그런데 이 방식의 문제점이 있다.
- 가독성이 너무 구리다⭐️(이게 제일 핵심이다)
→ 유지보수가 힘들 것 같다.
지금 이 포스팅을 하면서도 내가 무슨 코드를 짰는지 기억이 안나서 구글링했다.. - 지금 이 방식은 서버가 처리한 결과 데이터를 다시 클라이언트 쪽에서 값을 재배치해줘야 한다.
form 형태로 보내면 알아서 처리해주니까 지금 방식이 효율적인 방식이 아니라는 생각이 들었다.
검색만을 위한 /search 함수를 만드는것보다는 기존에 있는 list에서 필터링과 관련된 모든 로직을 처리하는것이 좋을 것 같다.
2. 두 번째 방법
이 방법으로 갈것 같다! 기존의 방식은 결과데이터를 어떻게 처리할 지에 대해서 고민하다가 가독성 이슈로 과감하게 포기했고, form의 형태로 처리하기로 했다.
기존에 내가 form 방식을 고려했다가 포기한 이유는 다음과 같다.
버튼에 있는 값을 List형태로 보내야하는데 같은 id를 가지고 있는 데이터를 list의 형태로 보내는것이 checkbox 말고는 안되는 걸로 알고 있기 때문이다.
아무리 구글링을 해봐도 잘 모르겠어서.. 그냥 클릭 액션 처리할 겸 ajax를 쓴건데 checkbox를 한번 잘 숨겨서 처리해보자는 피드백을 받았다!
See the Pen [포스팅] checkbox를 숨겨서 클릭이벤트 처리하기 by 박다정 (@lion0913) on CodePen.
내가 참고한 방식이다. 이렇게 보면 이해가 힘들 수도 있지만 opacity를 주석처리하면


이렇게!
이렇게 체크박스를 처리해주면 form을 list 형태로 보낼 수 있고, 버튼의 모양 그대로를 챙길 수 있어서 내가 의도한 그림과 일치한당
그렇다면 얘를 이제 프로젝트에 적용해보자!
과감하게 ajax 처리부분을 삭제해버리고 list.html 부분을 손봤다.
<div th:each="category,index:${categoryList}">
<input type="checkbox" name="category" th:value="${category.id}">
<div th:text="${category.tagName}" type="button" class="btn btn-outline-info"></div>
</div>
codepen에 올린대로 input과 div를 한쌍으로 두고, input의 타입을 checkbox로 설정해 list 형태를 처리할 수 있게 했다. 그리고 이 input이 서버에게 넘겨줄 값인 id를 가지고 있다.
같은 라인에 버튼을 꾸며주기위해서 버튼을 넣고 본격적으로 css 입히기를 시작했다..
codepen에서의 css 코드와 크게 달라진 점은 없다. 색깔과 테두리 둥글기정도??
.gather-category input[type="checkbox"]:checked + div {
color:white;
background-color: #01C9C6;
}
.gather-category > div {
display: inline-block;
position: relative;
}
.gather-category > div > input[type="checkbox"] {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
opacity: 0;
}
.gather-category > div > div {
color:#01C9C6;
font-size: 14px;
outline-color: #01C9C6;
margin-right: 15px;
margin-bottom: 10px;
padding: 10px 20px;
border-radius: 25px;
white-space: nowrap;
}
position을 relative, absolute 관계로 각각 두면서, 내부 박스가 button 안에 들어가게 했고, checkbox의 투명도를 최대로 했다고 요약할 수 있다..ㅎㅎ (css 코드가 너무 지저분한데 건드릴 엄두가 나지 않는다)
이렇게 해서 코드를 실행시키면!

클릭 시 색깔이 이렇게 예쁘게 들어간다…ㅎㅎ 너무 귀엽다!

결과화면이다!! 못생긴 검색화면 배치는 무시해주길 바란다.. 곧 예쁘게 꾸며줄거다.
'💻 Project > project' 카테고리의 다른 글
[DB] Mysql 한글깨짐, Mariadb 한글깨짐 해결방법 (0) | 2022.09.06 |
---|