ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 쇼핑몰 프로젝트 --별 기능(화면구현)
    쇼핑몰 프로젝트 2024. 6. 26. 19:02

     

     

    아이템 전체 리스트, 카테고리 별 아이템 리스트에 별 표시되게 하는 거 추가

     

    item/itemList (itemCategoryList 도 동일하게 추가해서 따로 안적음)

    <!DOCTYPE html>
    <html xmlns:th="http://www.thymeleaf.org" lang="en">
    
    <head th:replace="frame/header :: head">
        <title>Zay Shop - Product Listing Page</title>
    </head>
    
    <style>
        .fixed-size-img {
            width: 300px; /* 원하는 너비로 설정 */
            height: 300px; /* 원하는 높이로 설정 */
            object-fit: cover; /* 이미지를 크기에 맞게 조정 */
        }
    </style>
    
    <body>
    <!--header-->
    <header th:replace="frame/header :: header"></header>
    
    <!-- Start Content -->
    <div class="container py-5">
        <div class="row">
    
    
            <div class="container-fluid mt-3">
                <div class="row">
                    <div class="col-md-12">
                        <ul class="list-inline shop-top-menu pb-3 pt-1">
                            <li class="list-inline-item">
                                <a class="h3 text-dark text-decoration-none mr-3" th:href="@{/ypjs/item/post}">상품 등록</a>
                            </li>
                            <li class="list-inline-item">
                                <a class="h3 text-dark text-decoration-none mr-3" th:href="@{/ypjs/category/post}">카테고리 등록</a>
                            </li>
                            <li class="list-inline-item">
                                <a class="h3 text-dark text-decoration-none mr-3" th:href="@{/ypjs/category/get}">카테고리 보기</a>
                            </li>
    
                        </ul>
                    </div>
                </div>
            </div>
    
    
    
            <div class="col-lg-3">
                <h1 class="h2 pb-4">Categories</h1>
                <ul class="list-unstyled templatemo-accordion">
                    <li class="pb-3">
                        <a class="collapsed d-flex justify-content-between h3 text-decoration-none" href="#">
                            Women
                            <i class="fa fa-fw fa-chevron-circle-down mt-1"></i>
                        </a>
                        <ul class="collapse show list-unstyled pl-3">
                            <li><a class="text-decoration-none" th:href="@{/ypjs/categoryItem/get/{categoryId}(categoryId=3)}">Outer</a></li>
                            <li><a class="text-decoration-none" th:href="@{/ypjs/categoryItem/get/{categoryId}(categoryId=4)}">Top</a></li>
                            <li><a class="text-decoration-none" th:href="@{/ypjs/categoryItem/get/{categoryId}(categoryId=5)}">Bottom</a></li>
                        </ul>
                    </li>
                    <li class="pb-3">
                        <a class="collapsed d-flex justify-content-between h3 text-decoration-none" href="#">
                            Man
                            <i class="pull-right fa fa-fw fa-chevron-circle-down mt-1"></i>
                        </a>
                        <ul id="collapseTwo" class="collapse list-unstyled pl-3">
                            <li><a class="text-decoration-none" th:href="@{/ypjs/categoryItem/get/{categoryId}(categoryId=6)}">Outer</a></li>
                            <li><a class="text-decoration-none" th:href="@{/ypjs/categoryItem/get/{categoryId}(categoryId=7)}">Top</a></li>
                            <li><a class="text-decoration-none" th:href="@{/ypjs/categoryItem/get/{categoryId}(categoryId=8)}">Bottom</a></li>
                        </ul>
                    </li>
    
                </ul>
            </div>
    
    
    
    
    
    
    
            <div class="col-lg-9">
                <div class="row">
                    <div class="col-md-6">
                        <ul class="list-inline shop-top-menu pb-3 pt-1">
                            <li class="list-inline-item">
                                <a class="h3 text-dark text-decoration-none mr-3" th:href="@{/ypjs/item/get}">All Items</a>
                            </li>
    
                        </ul>
                    </div>
    
    
    
    
    
    <!--                <div class="col-md-6">-->
    <!--                <form action="#" th:action="@{/ypjs/item/get}" method="get">-->
    <!--                <div class="col-md-6 pb-4">-->
    <!--                    <div class="d-flex">-->
    <!--                        <select class="form-control" name="sortBy" id="sortBy" onchange="this.form.submit()">-->
    <!--                            <option value="itemId" th:selected="${sortBy == 'itemId'}">최신순</option>-->
    <!--                            <option value="itemRatings" th:selected="${sortBy == 'itemRatings'}">별점 높은 순</option>-->
    <!--                            <option value="likeCount" th:selected="${sortBy == 'likeCount'}">찜많은순</option>-->
    <!--                        </select>-->
    <!--                    </div>-->
    <!--                </div>-->
    
    <!--            </form>-->
    <!--                </div>-->
    
    
    
    <!--                <div class="container">-->
    <!--                    <div class="row">-->
    <!--                        <div class="col-lg-9">-->
    <!--                            &lt;!&ndash; 검색 폼 &ndash;&gt;-->
    <!--                            <form th:action="@{/ypjs/item/get}" method="get">-->
    <!--                                <div class="form-row align-items-center mb-3">-->
    <!--                                    <div class="col-auto">-->
    <!--                                        <label for="keyword" class="sr-only">Keyword</label>-->
    <!--                                        <input type="text" id="keyword" name="keyword" class="form-control"-->
    <!--                                               placeholder="Search by item name" th:value="${keyword}">-->
    <!--                                    </div>-->
    <!--                                    <div class="col-auto">-->
    <!--                                        <button type="submit" class="btn btn-primary">Search</button>-->
    <!--                                    </div>-->
    <!--                                </div>-->
    <!--                            </form>-->
    <!--                        </div>-->
    <!--                    </div>-->
    
    
    
    
    
    
                    <div class="col-lg-6">
                        <!-- 검색 폼 및 정렬 폼 통합 -->
                        <form th:action="@{/ypjs/item/get}" method="get" class="input-group">
                            <input type="text" id="keyword" name="keyword" class="form-control"
                                   placeholder="제목으로 검색하기" th:value="${keyword}">
                            <div class="input-group-append">
                                <button type="submit" class="btn btn-link text-dark">
                                    <i class="fa fa-search"></i>
                                </button>
                            </div>
                            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
                            <div class="col-auto">
                                <select class="form-control" name="sortBy" id="sortBy" onchange="this.form.submit()">
                                    <option value="itemId" th:selected="${sortBy == 'itemId'}">최신순</option>
                                    <option value="itemRatings" th:selected="${sortBy == 'itemRatings'}">별점 높은 순</option>
                                    <option value="likeCount" th:selected="${sortBy == 'likeCount'}">찜많은순</option>
                                </select>
                            </div>
                        </form>
                    </div>
    
    
    
    
    
    <!--                반별 추가-->
    
    <!--                <div class="container-fluid mt-3">-->
    <!--                    <div class="row">-->
    <!--                        &lt;!&ndash; items 리스트의 각 항목을 반복 &ndash;&gt;-->
    <!--                        <div th:each="item : ${items}" class="col-md-4">-->
    <!--                            <div class="card mb-4 product-wap rounded-0">-->
    <!--                                &lt;!&ndash; 제품 이미지 &ndash;&gt;-->
    <!--                                <div class="card rounded-0">-->
    <!--                                    <a th:href="@{/ypjs/item/get/{itemId}(itemId=${item.itemId})}">-->
    <!--                                        <img class="card-img rounded-0 img-fluid fixed-size-img" th:src="${item.itemFilePath}" alt="product-item">-->
    <!--                                        &lt;!&ndash; 필요한 경우 오버레이나 추가 요소를 여기에 추가할 수 있습니다 &ndash;&gt;-->
    <!--                                        <div class="card-img-overlay rounded-0 product-overlay d-flex align-items-center justify-content-center">-->
    <!--                                            &lt;!&ndash; 추가적인 콘텐츠가 필요하다면 여기에 추가할 수 있습니다 &ndash;&gt;-->
    <!--                                            <ul class="list-unstyled">-->
    <!--                                                &lt;!&ndash; 리스트의 다른 요소들 &ndash;&gt;-->
    <!--                                            </ul>-->
    <!--                                        </div>-->
    <!--                                    </a>-->
    <!--                                </div>-->
    <!--                                &lt;!&ndash; 제품 정보 &ndash;&gt;-->
    <!--                                <div class="card-body">-->
    <!--                                    &lt;!&ndash; 제품 링크 &ndash;&gt;-->
    <!--                                    <a th:href="@{/ypjs/item/get/{itemId}(itemId=${item.itemId})}" id="itemName" class="font-weight-bold" th:text="${item.itemName}"></a>-->
    
    <!--                                    &lt;!&ndash; 별점 및 평점 표시 &ndash;&gt;-->
    <!--                                    <div class="d-flex justify-content-center mb-1 align-items-center">-->
    <!--                                        <ul class="list-unstyled d-flex mb-0" id="starRating" th:attr="data-rating=${item.itemRatings}">-->
    <!--                                            &lt;!&ndash; 별 아이콘은 JavaScript로 생성됩니다 &ndash;&gt;-->
    <!--                                        </ul>&nbsp;&nbsp;&nbsp;&nbsp;-->
    <!--                                        <span id="itemRatings" class="font-weight-bold ml-2" th:text="${item.itemRatings}"></span>-->
    <!--                                    </div>-->
    
    <!--                                    &lt;!&ndash; 가격 표시 &ndash;&gt;-->
    <!--                                    <span id="itemPrice" class="font-weight-bold" th:text="${item.itemPrice}"></span>-->
    <!--                                    <span class="font-weight-bold">원</span>-->
    <!--                                </div>-->
    <!--                            </div>-->
    <!--                        </div>-->
    <!--                    </div>-->
    <!--                </div>-->
    
    <!--                <script>-->
    <!--                    document.addEventListener("DOMContentLoaded", function() {-->
    <!--                        var starRatingContainers = document.querySelectorAll("#starRating");-->
    
    <!--                        starRatingContainers.forEach(function(starRatingContainer) {-->
    <!--                            var rating = parseFloat(starRatingContainer.getAttribute("data-rating"));-->
    <!--                            starRatingContainer.innerHTML = generateStarRating(rating);-->
    <!--                        });-->
    <!--                    });-->
    
    <!--                    function generateStarRating(rating) {-->
    <!--                        var starsHTML = '';-->
    <!--                        var fullStars = Math.floor(rating);  // 정수 부분의 별 개수-->
    <!--                        var halfStar = (rating % 1 >= 0.1 && rating % 1 <= 0.9) ? 1 : 0; // 반 별 조건-->
    
    <!--                        // 정수 부분의 별 추가-->
    <!--                        for (var i = 0; i < fullStars; i++) {-->
    <!--                            starsHTML += '<i class="text-warning fa fa-star"></i>';-->
    <!--                        }-->
    
    <!--                        // 반 별 추가-->
    <!--                        if (halfStar) {-->
    <!--                            starsHTML += '<i class="text-warning fa fa-star-half-alt"></i>';-->
    <!--                        }-->
    
    <!--                        // 남은 빈 별 추가-->
    <!--                        var emptyStars = 5 - fullStars - halfStar;-->
    <!--                        for (var i = 0; i < emptyStars; i++) {-->
    <!--                            starsHTML += '<i class="text-muted fa fa-star"></i>';-->
    <!--                        }-->
    
    <!--                        return starsHTML;-->
    <!--                    }-->
    <!--                </script>-->
    
    
    
    
    
    <!--                꽉찬 별만-->
                    <div class="container-fluid mt-3">
                        <div class="row">
                            <!-- items 리스트의 각 항목을 반복 -->
                            <div th:each="item : ${items}" class="col-md-4">
                                <div class="card mb-4 product-wap rounded-0">
                                    <!-- 제품 이미지 -->
                                    <div class="card rounded-0">
                                        <a th:href="@{/ypjs/item/get/{itemId}(itemId=${item.itemId})}">
                                            <img class="card-img rounded-0 img-fluid fixed-size-img" th:src="${item.itemFilePath}" alt="product-item">
                                            <!-- 필요한 경우 오버레이나 추가 요소를 여기에 추가할 수 있습니다 -->
                                            <div class="card-img-overlay rounded-0 product-overlay d-flex align-items-center justify-content-center">
                                                <!-- 추가적인 콘텐츠가 필요하다면 여기에 추가할 수 있습니다 -->
                                                <ul class="list-unstyled">
                                                    <!-- 리스트의 다른 요소들 -->
                                                </ul>
                                            </div>
                                        </a>
                                    </div>
                                    <!-- 제품 정보 -->
                                    <div class="card-body">
                                        <!-- 제품 링크 -->
                                        <a th:href="@{/ypjs/item/get/{itemId}(itemId=${item.itemId})}" id="itemName" class="font-weight-bold" th:text="${item.itemName}"></a>
    
                                        <!-- 별점 및 평점 표시 -->
                                        <div class="d-flex justify-content-center mb-1 align-items-center">
                                            <ul class="list-unstyled d-flex mb-0" id="starRating" th:attr="data-rating=${item.itemRatings}">
                                                <!-- 별 아이콘은 JavaScript로 생성됩니다 -->
                                            </ul> &nbsp;&nbsp;&nbsp;&nbsp;
                                            <span id="itemRatings" class="font-weight-bold ml-2" th:text="${item.itemRatings}"></span>
                                        </div>
    
                                        <!-- 가격 표시 -->
                                        <span id="itemPrice" class="font-weight-bold" th:text="${item.itemPrice}"></span>
                                        <span class="font-weight-bold">원</span>
                                    </div>
                                </div>
                            </div>
                        </div>
                    </div>
    
                    <script>
                        document.addEventListener("DOMContentLoaded", function() {
                            var starRatingContainers = document.querySelectorAll("#starRating");
    
                            starRatingContainers.forEach(function(starRatingContainer) {
                                var rating = parseFloat(starRatingContainer.getAttribute("data-rating"));
                                starRatingContainer.innerHTML = generateStarRating(rating);
                            });
                        });
    
                        function generateStarRating(rating) {
                            var starsHTML = '';
                            var numStars;
    
                            if (rating >= 0 && rating < 1) {
                                numStars = 0;
                            } else if (rating >= 1 && rating < 2) {
                                numStars = 1;
                            } else if (rating >= 2 && rating < 3) {
                                numStars = 2;
                            } else if (rating >= 3 && rating < 4) {
                                numStars = 3;
                            } else if (rating >= 4 && rating < 5) {
                                numStars = 4;
                            } else if (rating == 5) {
                                numStars = 5;
                            }
    
                            for (var i = 0; i < numStars; i++) {
                                starsHTML += '<i class="text-warning fa fa-star"></i>';
                            }
    
                            for (var i = numStars; i < 5; i++) {
                                starsHTML += '<i class="text-muted fa fa-star"></i>';
                            }
    
                            return starsHTML;
                        }
                    </script>
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
                </div>
            </div>
    
        </div>
    </div>
    <!-- End Content -->
    
    <!-- Start Brands -->
    <section class="bg-light py-5">
        <div class="container my-4">
            <div class="row text-center py-3">
                <div class="col-lg-6 m-auto">
                    <h1 class="h1">Our Brands</h1>
                    <p>
                        Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod
                        Lorem ipsum dolor sit amet.
                    </p>
                </div>
                <div class="col-lg-9 m-auto tempaltemo-carousel">
                    <div class="row d-flex flex-row">
                        <!--Controls-->
                        <div class="col-1 align-self-center">
                            <a class="h1" href="#multi-item-example" role="button" data-bs-slide="prev">
                                <i class="text-light fas fa-chevron-left"></i>
                            </a>
                        </div>
                        <!--End Controls-->
    
                        <!--Carousel Wrapper-->
                        <div class="col">
                            <div class="carousel slide carousel-multi-item pt-2 pt-md-0" id="multi-item-example" data-bs-ride="carousel">
                                <!--Slides-->
                                <div class="carousel-inner product-links-wap" role="listbox">
    
                                    <!--First slide-->
                                    <div class="carousel-item active">
                                        <div class="row">
                                            <div class="col-3 p-md-5">
                                                <a href="#"><img class="img-fluid brand-img" src="/img/brand_01.png" alt="Brand Logo"></a>
                                            </div>
                                            <div class="col-3 p-md-5">
                                                <a href="#"><img class="img-fluid brand-img" src="/img/brand_02.png" alt="Brand Logo"></a>
                                            </div>
                                            <div class="col-3 p-md-5">
                                                <a href="#"><img class="img-fluid brand-img" src="/img/brand_03.png" alt="Brand Logo"></a>
                                            </div>
                                            <div class="col-3 p-md-5">
                                                <a href="#"><img class="img-fluid brand-img" src="/img/brand_04.png" alt="Brand Logo"></a>
                                            </div>
                                        </div>
                                    </div>
                                    <!--End First slide-->
    
                                    <!--Second slide-->
                                    <div class="carousel-item">
                                        <div class="row">
                                            <div class="col-3 p-md-5">
                                                <a href="#"><img class="img-fluid brand-img" src="/img/brand_01.png" alt="Brand Logo"></a>
                                            </div>
                                            <div class="col-3 p-md-5">
                                                <a href="#"><img class="img-fluid brand-img" src="/img/brand_02.png" alt="Brand Logo"></a>
                                            </div>
                                            <div class="col-3 p-md-5">
                                                <a href="#"><img class="img-fluid brand-img" src="/img/brand_03.png" alt="Brand Logo"></a>
                                            </div>
                                            <div class="col-3 p-md-5">
                                                <a href="#"><img class="img-fluid brand-img" src="/img/brand_04.png" alt="Brand Logo"></a>
                                            </div>
                                        </div>
                                    </div>
                                    <!--End Second slide-->
    
                                    <!--Third slide-->
                                    <div class="carousel-item">
                                        <div class="row">
                                            <div class="col-3 p-md-5">
                                                <a href="#"><img class="img-fluid brand-img" src="/img/brand_01.png" alt="Brand Logo"></a>
                                            </div>
                                            <div class="col-3 p-md-5">
                                                <a href="#"><img class="img-fluid brand-img" src="/img/brand_02.png" alt="Brand Logo"></a>
                                            </div>
                                            <div class="col-3 p-md-5">
                                                <a href="#"><img class="img-fluid brand-img" src="/img/brand_03.png" alt="Brand Logo"></a>
                                            </div>
                                            <div class="col-3 p-md-5">
                                                <a href="#"><img class="img-fluid brand-img" src="/img/brand_04.png" alt="Brand Logo"></a>
                                            </div>
                                        </div>
                                    </div>
                                    <!--End Third slide-->
    
                                </div>
                                <!--End Slides-->
                            </div>
                        </div>
                        <!--End Carousel Wrapper-->
    
                        <!--Controls-->
                        <div class="col-1 align-self-center">
                            <a class="h1" href="#multi-item-example" role="button" data-bs-slide="next">
                                <i class="text-light fas fa-chevron-right"></i>
                            </a>
                        </div>
                        <!--End Controls-->
                    </div>
                </div>
            </div>
        </div>
    </section>
    <!--End Brands-->
    
    
    <footer th:replace="frame/footer :: footer"></footer>
    
    </body>
    
    </html>

     

     

     

     

     

     

     

    아이템 당 리뷰도 구현 

    item/itemGet

     

     

     

    리뷰쓰기에서 별점 구현 

    itemReview/itemReviewPost

    <!DOCTYPE html>
    <html xmlns:th="http://www.thymeleaf.org" lang="en">
    <head th:replace="frame/header :: head">
        <title>Zay Shop - Product Listing Page</title>
    </head>
    <body>
    <!--header-->
    <header th:replace="frame/header :: header"></header>
    
    <!-- Start Content -->
    <div class="container py-5">
        리뷰등록
    </div>
    <!-- End Content -->
    
    <!-- jQuery -->
    <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
    <!-- Summernote 스타일 및 스크립트 -->
    <link href="https://cdnjs.cloudflare.com/ajax/libs/summernote/0.8.18/summernote-bs4.min.css" rel="stylesheet">
    <script src="https://cdnjs.cloudflare.com/ajax/libs/summernote/0.8.18/summernote-bs4.min.js"></script>
    
    <!-- JS 파일 포함 -->
    <script src="/js/jquery-1.11.0.min.js"></script>
    <script src="/js/summernote-lite.js"></script>
    <script src="/js/summernote-ko-KR.js"></script>
    <script src="/js/item/itemReview.js"></script>
    <script src="/js/item/itemRatings.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/summernote/0.8.18/summernote.min.js"></script>
    
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.3/css/all.min.css">
    <style>
        .rating-stars {
            font-size: 24px; /* 별 아이콘 크기 */
            color: #ccc; /* 비어 있는 별 색상 */
            cursor: pointer; /* 포인터 커서 추가 */
        }
        .filled-star {
            color: gold; /* 채워진 별 색상 */
        }
    
    
    </style>
    
    <!-- Start Contact -->
    <div class="container py-5">
        <div class="row justify-content-center py-5">
    
            <!-- 폼 요소들 -->
            <div class="col-lg-8">
                <div class="row">
    
                    <input type="hidden" id="itemId" th:value="${item.itemId}" > <!-- Thymeleaf의 value 속성 사용 -->
                    <input type="hidden" id="memberId" value="1"> <!-- memberId 값 받아와야 됨 -->
    
                    <div class="form-group mb-3">
                        <label for="itemReviewName">제목</label>
                        <input type="text" class="form-control mt-1" id="itemReviewName" name="itemReviewName" placeholder="제목">
                    </div>
                    <br><br><br><br>
    
                    <div class="container">
                        <label for="itemScore">별점을 입력하세요</label>
                        <div id="starRating" class="mt-3">
                            <!-- 별 아이콘이 동적으로 추가될 위치 -->
                        </div>
                        <input type="hidden" id="itemScore" name="itemScore" value="0">
                    </div>
    
    
                    <BR><br><br><br>
                    <div class="form-group mb-3">
                        <label for="itemReviewContent">내용</label>
                        <textarea class="form-control" id="itemReviewContent" name="itemReviewContent" rows="10"></textarea>
                    </div>
    
                    <!-- Summernote 초기화 스크립트 -->
                    <script th:inline="javascript">
                        $(document).ready(function() {
                            $("#itemReviewContent").summernote({
                                height: 300, // 높이 설정
                                placeholder: '내용을 입력하세요...', // 플레이스홀더 설정
                                callbacks: {
                                    onChange: function(contents, $editable) {
                                        // 내용이 변경될 때 처리할 로직 추가 가능
                                    }
                                }
                            });
                        });
                    </script>
    
                    <!-- 글 등록 버튼 -->
                    <div class="row">
                        <div class="col text-end mt-2">
                            <button type="button" id="btn-itemReviewPost" class="btn btn-success btn-lg px-3">리뷰등록</button>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </div>
    <!-- End Contact -->
    
    <footer th:replace="frame/footer :: footer"></footer>
    </body>
    </html>
    

     

     

    itemRatings.js

    $(document).ready(function() {
        var initialScore = $('#itemScore').val(); // 기존의 itemScore 값 가져오기
        $('#starRating').html(generateStarRating(initialScore)); // 초기화: 기존의 별점으로 별 아이콘 표시
    
        // 별 아이콘 클릭 이벤트 리스너 추가
        $('#starRating').on('click', '.fa-star', function() {
            var score = $(this).data('score');
            $('#itemScore').val(score); // hidden 필드에 새로운 점수 설정
            $('#starRating').html(generateStarRating(score)); // 별 아이콘 업데이트
        });
    
        // 별 아이콘을 생성하여 HTML 문자열 반환하는 함수
        function generateStarRating(score) {
            var starsHTML = '';
            for (var i = 1; i <= 5; i++) {
                if (i <= score) {
                    starsHTML += '<i class="fas fa-star rating-stars filled-star" data-score="' + i + '"></i>';
                } else {
                    starsHTML += '<i class="fas fa-star rating-stars" data-score="' + i + '"></i>';
                }
            }
            return starsHTML;
        }
    });
    

     

     

    itemReview.js

    let itemBoardObject = {
        init: function() {
            let _this = this;
    
            $("#btn-itemReviewPost").on("click", function() {
                _this.insert();
            }),
             $("#btn-itemReviewUpdate").on("click", function() {
    
                        _this.update();
                    }),
    
             $(document).on("click", ".btn-delete-itemReview", function() {
                       // 클릭된 버튼의 데이터 속성에서 itemReviewId를 가져옴
                       let itemReviewId = $(this).data("itemreviewid");
    
                        // 아이템 리뷰 삭제 함수 호출
                       _this.deleteItemReview(itemReviewId);
                        });
    
    
        },
    
        insert: function() {
    
    
            let itemId = $("#itemId").val();  // URL에 사용할 itemId를 가져옴
            let itemScore = $("#itemScore").val(); // 별점 가져오기
            let itemReviewName = $("#itemReviewName").val(); // 제목 가져오기
    
    
                    // 별점을 선택하지 않은 경우 처리
                    if (itemScore === "0") {
                        alert("별점을 선택하세요.");
                        return; // 리뷰 등록 중단
                    }
    
                    // 제목이 비어 있는지 확인
                     if (!itemReviewName || itemReviewName.trim().length === 0) {
                          alert("제목을 입력하세요.");
                          return; // 리뷰 등록 중단
                      }
    
    
    
            let data = {
                itemId: itemId,  // itemId를 데이터에 포함
                memberId: $("#memberId").val(),  // 멤버 ID 추가
                itemReviewName: $("#itemReviewName").val(),
                itemScore: $("#itemScore").val(),
                itemReviewContent: $("#itemReviewContent").val(),
            };
    
    
    
    
    
            $.ajax({
                type: "POST",
                url: "/ypjs/itemReview/post/" + itemId,  // URL에 itemId를 추가
                data: JSON.stringify(data),
                contentType: "application/json; charset=utf-8",
                success: function(response) {
                    alert("리뷰가 등록되었습니다.");
                    window.location.href = "/ypjs/itemReview/get/" + itemId;  // 성공 후 리디렉션
                },
                error: function(error) {
                    alert("에러 발생: " + JSON.stringify(error));
                }
            });
        },
    
    
         update: function() {
    
            let itemReviewId = $("#itemReviewId").val();
             let itemScore = $("#itemScore").val(); // 별점 가져오기
    
                            // 별점을 선택하지 않은 경우 처리
                            if (itemScore === "0") {
                                alert("별점을 선택하세요.");
                                return; // 리뷰 등록 중단
                            }
    
    
                let updateData = {
    
                    itemReviewName: $("#itemReviewName").val(),
                    itemScore: $("#itemScore").val(),
                    itemReviewContent: $("#itemReviewContent").val(),
                };
    
                $.ajax({
                    type: "PUT",
    
                    url: "/ypjs/itemReview/update/" + itemReviewId,
                    data: JSON.stringify(updateData),
                    contentType: "application/json; charset=utf-8",
                    success: function(response) {
                    alert("리뷰가 수정되었습니다.");
                    window.location.href = "/ypjs/itemReview/get/" + response ;
    
                    },
                    error: function(error) {
                        alert("에러 발생: " + JSON.stringify(error));
                        // 에러 발생 시 적절히 처리하도록 수정이 필요할 수 있습니다.
                    }
                });
            },
    
    
    
    
             deleteItemReview: function(itemReviewId) {
    
                     let itemId = $("#itemId").val();
    
                     $.ajax({
                         type: "DELETE",
                         url: "/ypjs/itemReview/delete/" + itemReviewId,
                         success: function(response) {
                             alert("리뷰가 삭제되었습니다.");
    
                             window.location.href = "/ypjs/itemReview/get/" + itemId;
                         },
                         error: function(xhr, status, error) {
                             alert("에러 발생: " + error);
                         }
                     });
                 }
    
    
            };
    
    
    
    $(document).ready(function() {
        itemBoardObject.init();
    });
    
    
    
    
    

     

    별점 유효성검사 추가

     

     

    itemreview/itemReviewUpdate

    <!DOCTYPE html>
    <html xmlns:th="http://www.thymeleaf.org" lang="en">
    <head th:replace="frame/header :: head">
        <title>Zay Shop - Product Listing Page</title>
    </head>
    <body>
    <!--header-->
    <header th:replace="frame/header :: header"></header>
    
    <!-- Start Content -->
    <div class="container py-5">
        리뷰수정
    </div>
    <!-- End Content -->
    
    <!-- jQuery -->
    <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
    <!-- Summernote 스타일 및 스크립트 -->
    <link href="https://cdnjs.cloudflare.com/ajax/libs/summernote/0.8.18/summernote-bs4.min.css" rel="stylesheet">
    <script src="https://cdnjs.cloudflare.com/ajax/libs/summernote/0.8.18/summernote-bs4.min.js"></script>
    
    <!-- JS 파일 포함 -->
    <script src="/js/jquery-1.11.0.min.js"></script>
    <script src="/js/summernote-lite.js"></script>
    <script src="/js/summernote-ko-KR.js"></script>
    <script src="/js/item/itemReview.js"></script>
    <script src="/js/item/itemRatings.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/summernote/0.8.18/summernote.min.js"></script>
    
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.3/css/all.min.css">
    <style>
        .rating-stars {
            font-size: 24px; /* 별 아이콘 크기 */
            color: #ccc; /* 비어 있는 별 색상 */
            cursor: pointer; /* 포인터 커서 추가 */
        }
        .filled-star {
            color: gold; /* 채워진 별 색상 */
        }
    </style>
    
    <!-- Start Contact -->
    <div class="container py-5">
        <div class="row justify-content-center py-5">
            <!-- 폼 요소들 -->
            <div class="col-lg-8">
                <div class="row">
                    <input type="hidden" id="itemReviewId" th:value="${itemReview.itemReviewId}">
    
                    <div class="form-group mb-3">
                        <label for="itemReviewName">제목</label>
                        <input type="text" class="form-control mt-1" id="itemReviewName" name="itemReviewName" th:value="${itemReview.itemReviewName}" placeholder="제목">
                    </div>
    
                    <div class="container">
                        <div id="starRating" class="mt-3" data-rating="${itemReview.itemScore}">
                            <!-- 별 아이콘이 동적으로 추가될 위치 -->
                        </div>
                        <input type="hidden" id="itemScore" name="itemScore" th:value="${itemReview.itemScore}" value="0">
                    </div>
    
    
    
                </div>
    
                <div class="mb-3">
                    <label for="itemReviewContent">내용</label>
                    <textarea class="form-control" id="itemReviewContent" name="itemReviewContent" th:text="${itemReview.itemReviewContent}" rows="10"></textarea>
                </div>
    
                <!-- Summernote 초기화 스크립트 -->
                <script th:inline="javascript">
                    $(document).ready(function() {
                        $("#itemReviewContent").summernote({
                            height: 300, // 높이 설정
                            placeholder: '내용을 입력하세요...', // 플레이스홀더 설정
                            callbacks: {
                                onChange: function(contents, $editable) {
                                    // 내용이 변경될 때 처리할 로직 추가 가능
                                }
                            }
                        });
                    });
                </script>
    
                <!-- 글 등록 버튼 -->
                <div class="row">
                    <div class="col text-end mt-2">
                        <button type="button" id="btn-itemReviewUpdate" class="btn btn-success btn-lg px-3">리뷰수정</button>
                    </div>
                </div>
            </div>
        </div>
    </div>
    <!-- End Contact -->
    
    <footer th:replace="frame/footer :: footer"></footer>
    </body>
    </html>
    

     

     

    별점 받아오기 itemRatings.js에 

    var initialScore = $('#itemScore').val();

    $('#starRating').html(generateStarRating(initialScore));

    이거 추가 위에 올라간 js는 이미 추가 된 js

     

     

     

    아이템 리뷰 목록

    itemreview/itemReviewGet

    <!DOCTYPE html>
    <html xmlns:th="http://www.thymeleaf.org" lang="en">
    
    <head th:replace="frame/header :: head">
        <title>Zay Shop - Product Listing Page</title>
    </head>
    
    <body>
    <!--header-->
    <header th:replace="frame/header :: header"></header>
    
    <!-- Start Content -->
    <div class="container py-5">
        아이템 리뷰
    </div>
    <!-- End Content -->
    
    
    <!-- jQuery -->
    <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
    
    
    
    
    <!-- JS 파일 포함 -->
    <script src="/js/jquery-1.11.0.min.js"></script>
    <script src="/js/summernote-lite.js"></script>
    <script src="/js/summernote-ko-KR.js"></script>
    <script src="/js/item/itemReview.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/summernote/0.8.18/summernote.min.js"></script>
    
    
    
    
    <!-- Start Contact -->
    <div class="container py-5">
        <div class="row py-5">
            <form  class="col-md-9 m-auto" method="post"  >
                <!-- 폼 요소들 -->
                <div class="row">
    
    
    
    
    
                    <style>
                        .category-box {
                            border: 1px solid #ccc;
                            padding: 10px;
                            margin-bottom: 10px;
                        }
    
                        .category-label {
                            font-weight: bold;
                        }
    
                        .item-box {
        border: 1px solid #ccc;
        padding: 10px;
        margin-bottom: 10px;
    }
    
    .item-info {
        /* Optional: Add additional styles for item information */
    }
    
    .category-label {
        font-weight: bold;
    }
    
    
                    </style>
    
    
    
    
    
    
    
                    <div th:if="${not #lists.isEmpty(itemReviews)}">
                        <br><br><br>
                        <h3>리뷰 목록</h3>
                        <br>
                        <div th:each="itemReview : ${itemReviews}" class="item-box">
                            <div class="item-info">
                                <div>
                                    <span class="category-label">아이템 이름&nbsp;&nbsp;&nbsp;&nbsp;:&nbsp;&nbsp;&nbsp;&nbsp;</span>
                                    <span th:text="${itemReview.itemReviewName}"></span>
                                </div>
                                <!-- 별점 및 평점 표시 -->
                                <div class="d-flex justify-content-left mb-1 align-items-left">
                                    <span class="category-label">별점&nbsp;&nbsp;&nbsp;&nbsp;:&nbsp;&nbsp;&nbsp;&nbsp;</span>
                                    <ul class="list-unstyled d-flex mb-0" id="starRating" th:attr="data-rating=${itemReview.itemScore}">
                                        <!-- 별 아이콘은 JavaScript로 생성됩니다 -->
                                    </ul>
    
                                </div>
                                <script>
                                    document.addEventListener("DOMContentLoaded", function() {
                                        var starRatingContainers = document.querySelectorAll("#starRating");
    
                                        starRatingContainers.forEach(function(starRatingContainer) {
                                            var rating = parseFloat(starRatingContainer.getAttribute("data-rating"));
                                            starRatingContainer.innerHTML = generateStarRating(rating);
                                        });
                                    });
    
                                    function generateStarRating(rating) {
                                        var starsHTML = '';
                                        var numStars;
    
                                        if (rating >= 0 && rating < 1) {
                                            numStars = 0;
                                        } else if (rating >= 1 && rating < 2) {
                                            numStars = 1;
                                        } else if (rating >= 2 && rating < 3) {
                                            numStars = 2;
                                        } else if (rating >= 3 && rating < 4) {
                                            numStars = 3;
                                        } else if (rating >= 4 && rating < 5) {
                                            numStars = 4;
                                        } else if (rating == 5) {
                                            numStars = 5;
                                        }
    
                                        for (var i = 0; i < numStars; i++) {
                                            starsHTML += '<i class="text-warning fa fa-star"></i>';
                                        }
    
                                        for (var i = numStars; i < 5; i++) {
                                            starsHTML += '<i class="text-muted fa fa-star"></i>';
                                        }
    
                                        return starsHTML;
                                    }
                                </script>
    
    
    
    
    
                                <div>
                                    <span class="category-label">리뷰 내용&nbsp;&nbsp;&nbsp;&nbsp;:&nbsp;&nbsp;&nbsp;&nbsp;</span>
                                    <div style="text-align: left;">
                                        <!-- 썸머노트에서 입력한 리뷰 내용 -->
                                        <div id="reviewContent" th:utext="${itemReview.itemReviewContent}">
                                            <!-- 썸머노트에서 삽입된 이미지의 스타일 -->
                                            <style>
                                                #reviewContent img {
                                                    display: block; /* 이미지가 한 줄에 나타나도록 설정 */
                                                    margin: auto; /* 가운데 정렬 */
                                                    max-width: 100%; /* 최대 너비 설정 */
                                                    height: auto; /* 높이 자동으로 조정 */
                                                    margin-bottom: 10px; /* 이미지 아래 여백 추가 */
                                                }
                                            </style>
                                        </div>
                                    </div>
                                </div>
    
    
    
    
                                <input type="hidden" id="itemId" th:value="${itemReview.itemId}">
                                <!-- 수정 및 삭제 버튼 -->
                                <div class="container">
                                    <div class="row justify-content-end">
                                        <div class="col-auto">
                                            <a th:href="@{/ypjs/itemReview/update/{itemReviewId}(itemReviewId=${itemReview.itemReviewId})}" class="btn btn-warning">수정하기</a>
                                        </div>
                                        <div class="col-auto">
    
                                            <button type="button"
                                                    class="btn btn-danger btn-sm btn-delete-itemReview"
                                                    th:data-itemReviewId="${itemReview.itemReviewId}"
    
                                                    style="padding: 2px 10px; font-size: 16px; width: 90px; height: 40px;">
                                                삭제하기
                                            </button>
                                        </div>
    
                                    </div>
                                </div>
                            </div>
                        </div>
                    </div>
    
    
                    <!-- End Contact -->
    
    
                </div>
            </form>
        </div>
    </div>
    
    
    <footer th:replace="frame/footer :: footer"></footer>
    
    </body>
    
    </html>
    

     

     

     

    썸네일 유효성 검사

    // 폼 제출 전 유효성 검사
       $('form').submit(function(event) {
         var fileInput = document.getElementById('file');
             if (fileInput.files.length === 0) {
                 alert('썸네일 파일을 선택하세요.');
                 event.preventDefault(); // 폼 제출 방지
              }
          });

     

    이부분 itme/itemPost, item/itemUpdate에 추가

    예) item/itemPost

    <!-- Summernote 초기화 스크립트 -->
    <script th:inline="javascript">
        $(document).ready(function() {
            $("#itemContent").summernote({
                height: 600, // 높이 설정
                placeholder: '상품 내용을 입력하세요...', // 플레이스홀더 설정
                callbacks: {
                    onChange: function(contents, $editable) {
                        // 내용이 변경될 때 처리할 로직 추가 가능
                    }
                }
            });
        });
    
        // 파일명을 표시하는 함수
        function displayFileName(input) {
            if (input.files.length > 0) {
                var fileName = input.files[0].name;
                document.getElementById('file-name-display').innerText = '선택된 파일: ' + fileName;
            } else {
                document.getElementById('file-name-display').innerText = '';
            }
        }
    
        // 폼 제출 전 유효성 검사
           $('form').submit(function(event) {
             var fileInput = document.getElementById('file');
                 if (fileInput.files.length === 0) {
                     alert('썸네일 파일을 선택하세요.');
                     event.preventDefault(); // 폼 제출 방지
                  }
              });
    </script>
    

     

    여기에 추가 그러면 

     

     

     

    이렇게 뜸

Designed by Tistory.