본문 바로가기

카테고리 없음

[여행 커뮤니티 만들기 (3)] 페이지 디자인 구현 with Springboot, JSP

✅ 메인 페이지

✅ 같이 여행 가요! - 게시판

✅ DB ➡ 드롭 다운

✅ 같이 여행 가요! - 작성 페이지

🌟community/travel_together_post.jsp

<div class="content">
    <div class="main-container">
        <div class="travel-container">
            <div class="header-container">
                <div style="flex: 1; display: flex; align-items: center;">
                    <h1>같이 여행 가요!</h1>
                </div>
            </div>
        </div>

        <div class="background-container" style="margin-top: 4%">
            <div class="country-container">
                <label>어느 나라로 갈까요?</label>
                <select id="options" name="options">
                    <c:forEach items="${options}" var="option">
                        <option value="${option.country}-${option.city}">
                                ${option.country} - ${option.city}
                        </option>
                    </c:forEach>
                </select>
            </div>
            <div class="country-container" style="margin-top: 3%">
                <label>언제 갈까요?</label>
                <input type="text" id="start-date" placeholder="날짜 선택" readonly>
                <input type="text" id="end-date" placeholder="날짜 선택" readonly>
            </div>
            <div class="country-container" style="margin-top: 3%">
                <label>몇 명을 모집할까요?</label>
                <input type="number" id="recruitedNum" placeholder="0에서 300 사이 숫자 입력">
            </div>
            <div class="country-container" style="margin-top: 3%">
                <label>언제까지 모집할까요?</label>
                <input type="text" id="deadline" placeholder="날짜 선택" readonly>
            </div>
        </div>
        <div class="background-container" style="margin-top: 4%">
            <form>
                <label for="title" class="label">제목</label>
                <input type="text" id="title" name="title" required>
                <label for="content" class="label">내용</label>
                <textarea id="content" required></textarea><br><br>
                <button class="search-button" id="submitButton">작성하기</button>
            </form>
        </div>
    </div>
</div>
<script>
    /** 어느 나라로 갈까요? */
    const selectBox = document.getElementById("options");
    selectBox.addEventListener("change", () => {
        // 선택한 값을 가져옴
        const selectedValue = selectBox.value;
        console.log("선택한 값: " + selectedValue);
    });

    /** 날짜 */
    $(function () {
        // 시작 날짜 선택
        $("#start-date").datepicker({
            dateFormat: "yy-mm-dd", // 날짜 형식 설정 (예: 2023-09-30)
            onSelect: function (dateText) {
                // 선택한 날짜를 텍스트 필드에 설정
                $("#start-date").val(dateText);
            }
        });

        // 끝 날짜 선택
        $("#end-date").datepicker({
            dateFormat: "yy-mm-dd", // 날짜 형식 설정 (예: 2023-09-30)
            onSelect: function (dateText) {
                // 선택한 날짜를 텍스트 필드에 설정
                $("#end-date").val(dateText);
            }
        });

        // 모집 마감 날짜
        $("#deadline").datepicker({
            dateFormat: "yy-mm-dd", // 날짜 형식 설정 (예: 2023-09-30)
            onSelect: function (dateText) {
                // 선택한 날짜를 텍스트 필드에 설정
                $("#deadline").val(dateText);
            }
        });
    });

    /** 모집 인원 - 0 ~ 300명 */
    var recruitedNum = document.getElementById('recruitedNum');
    recruitedNum.addEventListener('input', function () {
        var inputValue = parseFloat(recruitedNum.value);
        // 값이 0 이상 300 이하인지 확인
        if (inputValue < 0 || inputValue > 300) {
            alert('모집 인원은 0명 이상 300명 이하입니다.');
            recruitedNum.value = '';
        }
    });

    /** 제출 버튼 클릭 - 유효성 검사 */
    var submitButton = document.getElementById('submitButton');
    submitButton.addEventListener('click', function () {
        event.preventDefault(); // 기본 동작 중단

        var optionsValue = document.getElementById('options').value;
        var startDateValue = document.getElementById('start-date').value;
        var endDateValue = document.getElementById('end-date').value;
        var recruitedNumValue = parseFloat(document.getElementById('recruitedNum').value);
        var deadlineValue = document.getElementById('deadline').value;
        var errorMessage = '';

        if (!optionsValue) {
            errorMessage += '어느 나라로 갈지 선택하세요.\n';
        }
        if (!startDateValue) {
            errorMessage += '출발 날짜를 선택하세요.\n';
        }
        if (!endDateValue) {
            errorMessage += '도착 날짜를 선택하세요.\n';
        }
        if (!recruitedNumValue) {
            errorMessage += '인원 수를 입력하세요.\n';
        }
        if (!deadlineValue) {
            errorMessage += '마감일을 선택하세요.\n';
        }
        if (deadlineValue < 0 || deadlineValue > 300) {
            alert('모집 인원은 0명 이상 300명 이하입니다.');
            recruitedNum.value = '';
        }
        if (errorMessage) {
            alert(errorMessage);
        }
    });
</script>
  • 게시글을 작성할 때, 하나라도 작성하지 않으면 alert로 경고창이 뜨도록 설정
  • 모집 인원은 최소 0명부터 최대 300명까지 가능
  • 날짜 선택 시 datepicker로 캘린더가 띄워짐

✅ 여행에 대해 궁금해요!

✅ 나의 '같이 여행 가요!' 

🌟CommunityController

@Controller
@RequestMapping("/ROLE_USER")
public class CommunityController {

    @Autowired
    private CountryService countryService;
    @Autowired
    private UserService userService;

    /** 같이 여행 가요 */
    @GetMapping("/community/curious")
    public String curiousAboutTravelPage(Model model) {
        userService.getUserAndAddModel(model); // 사용자 정보 담기
        countryService.getCountriesAndAddModel(model); // 나라 데이터 담기
        return "community/curious_about_travel";
    }

    /** 여행에 대해 궁금해요 */
    @GetMapping("/community/together")
    public String travelTogetherPage(Model model) {
        userService.getUserAndAddModel(model); // 사용자 정보 담기
        countryService.getCountriesAndAddModel(model); // 나라 데이터 담기
        return "community/travel_together";
    }

    /** 여행에 대해 궁금해요 - 작성하기 페이지 */
    @GetMapping("/community/together/post")
    public String travelTogetherPost(Model model) {
        userService.getUserAndAddModel(model); // 사용자 정보 담기
        countryService.getCountriesAndAddModel(model); // 나라 데이터 담기
        return "community/travel_together_post";
    }

    /** 여행에 대해 궁금해요 - 작성하기 동작 */
    @PostMapping("/community/together/post")
    public String travelTogetherPostAction(Model model) {
        userService.getUserAndAddModel(model); // 사용자 정보 담기
        countryService.getCountriesAndAddModel(model); // 나라 데이터 담기
        return "community/travel_together_post";
    }
}
  • 페이지 매핑
    • @GetMapping
    • @PostMapping
  • userService.getUserAndAddModel(model) 
    • 사용자 정보를 model 객체에 담아 jsp 파일로 넘기기
    • 헤더에 '사용자님, 반갑습니다.' 동적 데이터를 띄우기 위해
  • countryService.getCountriesAndAddModel(model)
    • 나라 정보를 model 객체에 담아 jsp 파일로 넘기기
    • 어느 나라로 갈까요? 에서 드롭 다운으로 나라들 보기를 띄우기 위해

🌟CountryService

@Service
public class CountryService {

    @Autowired
    private CountryDao countryDao;

    /** 모든 나라 데이터 가져오기 */
    public List<CountryDto> findAllCountries() {
        return countryDao.findAllCountries();
    }

    /** 모든 나라 데이터 모델에 담기 */
    public void getCountriesAndAddModel(Model model) {
        model.addAttribute("options", findAllCountries());
    }
}

🌟CountryDao.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">

<mapper namespace="com.example.choyoujin.dao.CountryDao">
    <!--    모든 나라 가져오기-->
    <select id="findAllCountries" resultType="com.example.choyoujin.dto.CountryDto">
        select *
        from country_city
    </select>
</mapper>