2024-03-24 - 카페리스트 ajax 페이지네이션 구현 중

·2024년 3월 24일

프로젝트

목록 보기
35/57

📅 2024-03-24


필터검색 시 결과목록을 5번 반복하여 보여주는 문제 해결

var cafeListElement = $(".linkbox1");
var searchResult = $("#search-result");	

//cafeListElement.append(cafeItem); // AS-IS (요놈이 문제)
searchResult.append(cafeItem);	    // TO-BE
  • append는 선택자의 하위에 집어넣으라는건데 linkbox1을 선택 후 linkbox1의 하위에다가 cafeitem(html소스)을 집어넣어서 같은 카페목록을 5번 중복으로 보여주던거였다.
  • 그 상위인 search-result를 선택하여 append를 하니 해결.

카페 전체보기와 키워드검색결과보기를 하나의 메서드와 하나의 쿼리로 처리 하려고 했으나 실패

  • 카페 전체보기와 키워드검색결과보기를 하나의 메서드와 하나의 쿼리로 같이 쓰기 위해 (SearchList 메서드는 더이상 사용하지 않으려고) 아래 쿼리들로 시도했으나
    계속 myBatis 쿼리 에러가 뜸
  • 결국엔 기존 쿼리를 살려놓고, keyword를 태워왔을때 실행할 쿼리 한개를 더 만듬.
  • 그리고 searchList메서드도 그대로 살려놓고 (처음에 카페검색 페이지에 접속 했을 때 보여주기 위한), 기존 페이지에서 필터검색 사용시엔 cafeFilter메서드로 검색결과를 보여주기로 함.
//이것도 안되고..

			<script>
			     SELECT id, name, address, goodReactionPoint, reviewCount, hashtag, cafeImgUrl1
			     FROM cafe
				<isNotEmpty property="keyword">
			        WHERE `name` LIKE CONCAT('%', #{keyword}, '%')
			        OR `address` LIKE CONCAT('%', #{keyword}, '%')
			        OR `hashtag` LIKE CONCAT('%', #{keyword}, '%')
			    </isNotEmpty>
			     GROUP BY id
			     ORDER BY id DESC
			     <if test="limitFrom >= 0 ">
			         LIMIT #{limitFrom}, #{limitTake}
			     </if>
			</script>
			


//이것도 안돼서 위에 설명대로 개별적인 쿼리로 진행하기로 했고
//그렇게 하니 해결..

			<script>
			     SELECT id, name, address, goodReactionPoint, reviewCount, hashtag, cafeImgUrl1
			     FROM cafe
			     <where>
				    <if test='keyword != null and keyword.equals("") '>
				        AND (
				        `name` LIKE CONCAT('%', #{keyword}, '%')
				        OR `address` LIKE CONCAT('%', #{keyword}, '%')
				        OR `hashtag` LIKE CONCAT('%', #{keyword}, '%')
				        )
				    </if>
				</where>
			     GROUP BY id
			     ORDER BY id DESC
			     <if test="limitFrom >= 0 ">
			         LIMIT #{limitFrom}, #{limitTake}
			     </if>
			 </script>

문제의 원인을 드디어 찾음.
script 태그 안에서는 ">" "<" 부등호가 먹히지 않는다!
& gt;(greater than) & lt;(less than)을 사용해야했었다..


Ajax로 키워드검색결과 리스트 보여주기 & Ajax로 리스트 보여줄때 페이지네이션 업데이트

  • Ajax로 필터 키워드검색결과도 보여줘야하고 필터키워드만 해당되는 페이지네이션과 해당 페이지네이션으로 페이지 이동시에도 키워드가 유지되어야한다
  • 필터버튼을 눌렀을 때도, 그리고 페이지 이동시에도 Ajax로 처리해야해서 (keyword와 pagination 동시 처리) Ajax를 함수로 따로 만들어서 사용

loadFilteredCafes라는 함수를 만들어서 keyword와 pagination을 Ajax로 동시 처리한다

	// 필터 버튼 클릭 이벤트 핸들러 등록
    $(".filterButton").on("click", function(event) {
      
    	//keyword는 전역변수선언
        keyword = $(this).find(".text-wrapper").text(); // 클릭한 버튼의 text-wrapper에서 키워드 추출
        
     	// 필터링된 카페 목록을 요청하는 함수 호출
        loadFilteredCafes(keyword, currentPage);
    });
    
    // 페이지 이동 버튼 클릭 이벤트 핸들러
    $('.pagination').on('click', 'a', function(event) {
        var targetPage = parseInt($(this).attr('href').split('=')[1]); // 클릭한 페이지 번호
        
     	// 필터링된 카페 목록을 요청하는 함수 호출
        loadFilteredCafes(keyword, targetPage);
    });

loadFilteredCafes 함수

    function loadFilteredCafes(keyword, page){
    	$.ajax({
            url: "/usr/findcafe/filterCafes", // 실제 Ajax 요청을 처리할 URL
            type: "POST", // POST 요청으로 변경
            contentType: "application/json", // JSON 형식으로 데이터 전송
            data: JSON.stringify({
            	keyword: keyword, // 키워드를 JSON 형식으로 전송
                page: page // 페이지 번호도 함께 전송
            }), // 키워드를 JSON 형식으로 서버로 전송
            success: function(dataMap) {
                // Ajax 요청 성공 시 처리
                console.log("Filtered cafes:", dataMap.cafesCurrentList); // 받은 응답을 콘솔에 출력
				alert("카페 전체 리스트 : " + dataMap.cafesTotalCount + "\n현재page 노출 카페 리스트 : " + dataMap.cafesCurrentList.length);
                
                // 받은 응답을 사용하여 카페 목록을 업데이트하거나 화면에 출력하는 등의 작업 수행
                totalPages = Math.ceil(dataMap.cafesTotalCount / 5); // 전체 페이지 수 계산
                updatePagination(page, totalPages); // 페이지네이션 업데이트
                updateCafeList(dataMap.cafesCurrentList); // 카페 목록 업데이트
            },
            error: function(xhr, status, error) {
                // Ajax 요청 실패 시 처리
                console.error("Ajax request failed:", status, error);
            }
        });
        // 클릭 이벤트 핸들러를 한 번만 실행하도록 이벤트 핸들러 제거
        $(this).off(event);
    }

전체코드

<!-- Ajax 코드 -->
$(document).ready(function() {
	var currentPage = 1; // 초기 페이지 번호
    var totalPages = 1; // 전체 페이지 수
    var keyword = "";
    
 	// 필터 버튼 클릭 이벤트 핸들러 등록
    $(".filterButton").on("click", function(event) {
      
    	//keyword는 전역변수선언
        keyword = $(this).find(".text-wrapper").text(); // 클릭한 버튼의 text-wrapper에서 키워드 추출
        
     	// 필터링된 카페 목록을 요청하는 함수 호출
        loadFilteredCafes(keyword, currentPage);
    });
    
    // 페이지 이동 버튼 클릭 이벤트 핸들러
    $('.pagination').on('click', 'a', function(event) {
        var targetPage = parseInt($(this).attr('href').split('=')[1]); // 클릭한 페이지 번호
        
     	// 필터링된 카페 목록을 요청하는 함수 호출
        loadFilteredCafes(keyword, targetPage);
    });
    function loadFilteredCafes(keyword, page){
    	$.ajax({
            url: "/usr/findcafe/filterCafes", // 실제 Ajax 요청을 처리할 URL
            type: "POST", // POST 요청으로 변경
            contentType: "application/json", // JSON 형식으로 데이터 전송
            data: JSON.stringify({
            	keyword: keyword, // 키워드를 JSON 형식으로 전송
                page: page // 페이지 번호도 함께 전송
            }), // 키워드를 JSON 형식으로 서버로 전송
            success: function(dataMap) {
                // Ajax 요청 성공 시 처리
                console.log("Filtered cafes:", dataMap.cafesCurrentList); // 받은 응답을 콘솔에 출력
				alert("카페 전체 리스트 : " + dataMap.cafesTotalCount + "\n현재page 노출 카페 리스트 : " + dataMap.cafesCurrentList.length);
                
                // 받은 응답을 사용하여 카페 목록을 업데이트하거나 화면에 출력하는 등의 작업 수행
                totalPages = Math.ceil(dataMap.cafesTotalCount / 5); // 전체 페이지 수 계산
                updatePagination(page, totalPages); // 페이지네이션 업데이트
                updateCafeList(dataMap.cafesCurrentList); // 카페 목록 업데이트
            },
            error: function(xhr, status, error) {
                // Ajax 요청 실패 시 처리
                console.error("Ajax request failed:", status, error);
            }
        });
        // 클릭 이벤트 핸들러를 한 번만 실행하도록 이벤트 핸들러 제거
        $(this).off(event);
    }
    
        // 카페 목록을 업데이트하는 함수
        function updateCafeList(cafeList) {
            // 카페 목록을 표시할 HTML 요소를 가져온다
            var cafeListElement = $(".linkbox1");
            var searchResult = $("#search-result");		
            
            
            // 이전에 표시된 카페 목록을 초기화
            cafeListElement.empty();
            // 받은 cafeList를 사용하여 카페 목록을 업데이트
            cafeList.forEach( function(cafe) {
                // 각 카페에 대한 HTML 요소를 생성하여 cafeListElement에 추가
                // alert("카페 id=" + cafe.id); //cafe.id를 가져오는지 alert창으로 확인
                var cafeItem = $(`
                    <div class="cafe-item">
                        <a href="cafeDetail?id=`+cafe.id+` class="linkbox1">
                            <div class="content-info-box" style="margin-bottom: 50px">
                                <div class="cafe-img-box">
                                    <img src="`+cafe.cafeImgUrl1+`" alt="카페 이미지" />
                                </div>
                                <div class="name-address">
                                    <div class="cafe-name">`+cafe.name+`</div>
                                    <p class="cafe-address">`+cafe.address+`</p>
                                </div>
                                <div class="like-count">
                                    <span class="material-symbols-outlined"> favorite </span>
                                    <div class="like-count-num">`+cafe.goodReactionPoint+`</div>
                                </div>
                                <div class="review-count">
                                    <div class="title-review">리뷰</div>
                                    <div class="review-count-num">`+cafe.reviewCount+`</div>
                                </div>
                                <div class="show-distance">
                                    <div class="num-km-group">
                                        <div class="km">km</div>
                                        <div class="distance-num">1.8</div>
                                        <!-- 카페와의 거리 추가 -->
                                    </div>
                                </div>
                                <div class="hashtag">`+cafe.hashtag+`</div>
                            </div>
                        </a>
                    </div>
                `);
                //cafeListElement.append(cafeItem); // 5번반복보여준 원인
                searchResult.append(cafeItem);		
            }); // end cafeList.forEach
            
        } 
        
        // 페이지네이션 업데이트 함수
        function updatePagination(currentPage, totalPages) {
        	
        	///// 페이지네이션을 표시할 HTML 요소를 가져온다
            var paginationElement = $(".pagination");
        	///// 이전에 표시된 페이지네이션을 초기화
            paginationElement.empty();
        	
            var paginationHTML = '';
            // 페이지 번호 생성
            for (var i = 1; i <= totalPages; i++) {
                var activeClass = (i === currentPage) ? 'btn-active' : '';
                paginationHTML += '<a class="btn btn-circle btn-ghost btn-xs ' + activeClass + '" href="?page=' + i + '">' + i + '</a>';
            }
            $('.pagination').html(paginationHTML); // 페이지네이션 업데이트
        }
        
});

해결 (된줄알았지...?)

이제 필터에서 키워드버튼을 클릭하면 Ajax로 해당키워드에 맞는 카페 목록과 그 목록을 한페이지당 5개로 보여주면서 페이지네이션도 업데이트 된다.

문제상황

  • 페이지네이션도 분명 키워드별로 검색 된 카페 수에 맞게 클릭해야 할 숫자가 조절이 되는데...
  • 문제는 아직도 1페이지만 제대로 보여준다는 것..
  • 2페이지로 이동하면 Ajax처리하여 검색된 키워드의 카페를 보여주는 것이 아닌, 카페 전체리스트로 전환되며 2페이지로 넘어가버린다는 거다............ Ajax가 풀려버린다?라는 표현이 맞을까?ㅜㅜ
  • 페이지네이션도 보여지는 카페 수에 맞게 조절이 되는데..왜.......?????????
  • 2페이지로 이동시 Ajax로 키워드가 전달되게 세팅해놓았는데도 전달이 안되는 것 같다....... 왜..........?
  • 왜......................................... 도데체 왜..................
  • 좀 ㄷ ㅓ 고민해보자..

profile
hello world

0개의 댓글