본문 바로가기
ㆍ사이드 프로젝트

[SIDE] LUNCH - 5 / view (webapp 폴더 이하)

by 매이슨 2022. 3. 14.

우선 맵핑주소("/")  - index.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<html>
<head>
    
    <title>점심</title>
    <link href="./css/index.css" rel="stylesheet">
    <script src="https://code.jquery.com/jquery-3.4.1.js"></script>
</head>
<body>


<div class="loginContainer">
    <div class="loginBox">
        <h1>LUNCH</h1>
        <input type="text" name="id" id="id" placeholder="이름을 입력해주세요." autofocus onkeydown="if(event.keyCode == 13) doLogin();"/><br>
        <button onclick='doLogin();'>로그인</button>
    </div>
</div>


<script>
    function doLogin() {
        let id = document.getElementById('id').value;

        if( id.length === 0 ){
            alert('아이디를 입력하세요.')
            return false;
        }
        let MemberVO = {
            "id": id
        };
        $.ajax({
            type: 'POST',
            url: '/api/login',
            data: JSON.stringify(MemberVO),
            contentType : 'application/json;  charset=UTF-8',
            async: false,
            success: function(data) {
                if (data != null) {
                    // Do somothing when data is not null
                    if (data.result == 'success') {
                        location.href='/lunch';
                    } else {
                        alert('아이디정보가 없습니다.');
                        return false;
                    }
                }
            },
            error:function (e){
                console.log(e);
            }
        });
    }

</script>

</body>
</html>

특이사항 : 이름으로 로그인한다 input tag에 autofocus를 넣어주어 페이지 진입시 자동으로 커서이동


("/lunch") - lunch.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<html>
<head>
    <title>식당 선택하기</title>
    <link href="./css/lunch.css" rel="stylesheet">
    <script src="https://code.jquery.com/jquery-3.4.1.js"></script>
    <script src="//cdn.jsdelivr.net/npm/sweetalert2@11"></script>
    <script src="https://cdn.jsdelivr.net/npm/chart.js@2.9.4/dist/Chart.min.js"></script>
    <script src="https://cdn.jsdelivr.net/gh/emn178/chartjs-plugin-labels/src/chartjs-plugin-labels.js"></script>
    
</head><%----%><%----%><%----%><%----%><%----%><%----%><%----%><%----%><%----%><%----%>
<body onload="printClock()"><%----%><%----%><%----%><%----%><%----%><%----%><%----%>
<div class="popup_bg">
    <div class="append_popup append_store">
        <h3>식당 추가</h3>
        <div>
            <form>
                <dl>
                    <dt>식당 이름</dt>
                    <dd><input type="text" name="store" placeholder="식당 이름을 입력해주세요."></dd>
                </dl>
                <dl>
                    <dt>최소주문금액</dt>
                    <dd>
                        <input type="text" name="minimum_price" class="input_price" placeholder="최소주문금액을 입력해주세요.">원
                    </dd>
                </dl>
                <dl>
                    <dt>배달팁</dt>
                    <dd>
                        <input type="text" name="delivery_tip" class="input_price" placeholder="배달팁을 입력해주세요.">원
                    </dd>
                </dl>
                <dl>
                    <dt>배달설명</dt>
                    <dd>
                        <input type="text" name="delivery_detail" placeholder="배달설명을 입력해주세요.">
                    </dd>
                </dl>
            </form>
            <div class="btn_box">
                <button type="button" class="btn_append btn_append_mainMenu">추가</button>
                <button type="button" class="btn_cancel">취소</button>
            </div><%--.btn_box--%>
        </div>
    </div><%--.append_store--%>
</div><%--.popup_bg--%>

<div class="wraper">
    <div class="header">
        <h1 class="logo" onclick="location.reload()">식당 선택</h1>
        <div class="dateAndTime">
            <div id="date"></div>
            <div id="clock"></div>
        </div><%--.dateAndTime--%>
        
        <div class="myBox">
            <c:if test="${!empty choiceStore}">
                <%--<c:if  test="${choiceStore.store_seq eq 1}">--%>
                    <div class="myPick">
                        <dl>
                            <dt>
                                내가 선택한 사무실 :
                            </dt>
                            <dd>
                                <c:if test="${choiceStore.office eq 'OfficeB'}">
                                    사무실B
                                </c:if>
                                <c:if test="${choiceStore.office eq 'OfficeA'}">
                                    사무실A
                                </c:if>
                            </dd>
                        </dl>
                        <dl>
                            <dt>내가 선택한 식당 :</dt>
                            <dd>&nbsp;${choiceStore.storePicked}</dd>
                        </dl>
                    </div><%--.myPick--%>
                <%--</c:if>--%>
            </c:if>
            <button type="button" class="doNotEat" onclick="doNotEat()">식사 X</button>
            <button class="logout" onclick="location.href='/api/logout'">${id}님 로그아웃</button>
        </div><%--.myBox--%>
    </div>

    <div class="container">
        <div class="office">
            <h3>사무실 선택</h3>
            <c:if  test="${empty choiceStore}">
                <input type="radio" name="office" id="OfficeA" value="OfficeA"/><label for="OfficeA">사무실A</label>
                <input type="radio" name="office" id="OfficeB" value="OfficeB"/><label for="OfficeB">사무실B</label>
            </c:if>
            <c:if  test="${!empty choiceStore}">
                <c:if test="${choiceStore.office eq 'OfficeB'}">
                    <input type="radio" name="office" id="OfficeA" value="OfficeA"/><label for="OfficeA">사무실A</label>
                    <input type="radio" name="office" id="OfficeB" value="OfficeB" checked/><label for="OfficeB">사무실B</label>
                </c:if>
                <c:if test="${choiceStore.office eq 'OfficeA'}">
                    <input type="radio" name="office" id="OfficeA" value="OfficeA" checked/><label for="OfficeA">사무실A</label>
                    <input type="radio" name="office" id="OfficeB" value="OfficeB"/><label for="OfficeB">사무실B</label>
                </c:if>
            </c:if>
        </div>

        <div class="menu" id="menu">
            <c:choose>
                <c:when test="${empty storeList}">
                    등록된 식당이 없습니다.
                    새로고침 또는 식당을 DB에 추가해주세요.
                </c:when>
                <c:otherwise>
                    <c:forEach var="store" items="${storeList}">
                        <c:choose>
                            <c:when test="${choiceStore.storePicked eq store.store}">
                                <button class="store active" value="${store.store}">${store.store}</button>
                            </c:when>
                            <c:otherwise>
                                <button class="store" value="${store.store}">${store.store}</button>
                            </c:otherwise>
                        </c:choose>
                    </c:forEach>
                </c:otherwise>
            </c:choose>
            <button class="addStore">+</button>
        </div>
    </div><%--.container--%>
    
    <%-- 식당 선택 현황 시작 --%>
    <div class="storePicked">
        <div class="OfficeA">
        
        </div><%--.OfficeA--%>
        <div class="OfficeB">
        
        </div><%--.OfficeB--%>
    </div><%--.storePicked--%>
    
    <%-- 식당 선택 현황 끝 --%>
</div><%--.wraper--%>


<%-- 팝업 시작 --%>
<%--<div class="layer-popup" id="layer-popup">--%>
<%--    <div class="modal-dialog">--%>
<%--        <div class="modal-content">--%>
<%--            팝업 내용입니다.--%>
<%--        </div>--%>
<%--        <button type="button" class="btn-store-choice" id="btn-store-choice" onclick="pickingStore(this.value)">식당 선택하기</button>--%>
<%--    </div>--%>
<%--</div>--%>
<%-- 팝업 끝 --%>

<script>
    // 식사 안함
    function doNotEat(){
        Swal.fire({
            title: '정말 식사를 하지 않으시겠습니까?',
            text: "낙 장 불 입",
            icon: 'warning',
            showCancelButton: true,
            confirmButtonColor: '#3085d6',
            confirmButtonText: '네',
            cancelButtonColor: '#d33',
            cancelButtonText: '아니오'
        }).then((result) => {
            // 식사 진짜로 안함 확정
            if (result.isConfirmed) {
               
                $.ajax({
                    url:"/api/noLunchToday",
                    method : "POST",
                    success:function (data) {
                        if (data.result == 'success') {
                            Swal.fire({
                                title: '식사 X ',
                                icon: 'success',
                                confirmButtonText: '확인'
                            }).then((result) => {
                                if (result.isConfirmed) {
                                    location.reload();
                                }
                            });
                        }else {
                            alert('식사 X error')
                        }
                    },
                    error:function(e){
                        alert(e+"\nerror");
                    }
                });
            }
        })
    }

    // 식당 메뉴 팝업
    function popUpMenu(store){
        /*let target = $('').attr("href");*/
        let office_inputs = document.querySelector("input[name=office]:checked");
        
        if(!office_inputs){
            // 사무실 미선택
            Swal.fire({
                title: "사무실을 선택하셨나요?",
                text: "사무실을 선택하세요!",
                icon: "warning",//"info,success,warning,error" 중 택1
                confirmButtonText: "확인"
            });
        }else{
            // 사무실 선택
            $('.layer-popup').addClass("show");
            $('.modal-content').html('<img src="./img/'+store+'.jpg" alt="'+store+'대표메뉴사진'+'"/>');
            $('button#btn-store-choice').val(store);
        }
    }
    
    // 외부영역 클릭 시 팝업 닫기
    $(document).mouseup(function (e){
        let LayerPopup = $(".layer-popup");
        if(LayerPopup.has(e.target).length == 0){
            LayerPopup.removeClass("show");
        }
    });
</script>
<script>
    /* 날짜 및 시계  */
    function printClock() {  /* 시계  */
        let date = document.getElementById("date");
        let clock = document.getElementById("clock");  // 출력할 장소 선택
        let currentDate = new Date();  // 현재시간
        let calendar = currentDate.getFullYear() + "-" + (currentDate.getMonth() + 1) + "-" + currentDate.getDate(); // 현재 날짜
        let amPm = 'AM'; // 초기값 AM
        let currentHours = addZeros(currentDate.getHours(), 2);
        let currentMinute = addZeros(currentDate.getMinutes(), 2);
        let currentSeconds = addZeros(currentDate.getSeconds(), 2);

        if(currentHours >= 12){ // 시간이 12보다 클 때 PM으로 세팅, 12를 빼줌
            amPm = 'PM';
            // currentHours = addZeros(currentHours - 12,2);
        }
        
        // 10시 20분에 돌림판 돌리고
        // /menu로 넘기기 돌리기
        if(currentMinute == 20){
            if(currentHours == 10){
                Swal.fire({
                    title: ' 메뉴선택 페이지로 이동합니다 ',
                    icon: 'success',
                    confirmButtonText: '확인'
                }).then((result) => {
                    if (result.isConfirmed) {
                        location.href='./menu';
                    }
                });
            }
        }
        /*
            if(currentSeconds >= 50){ // 50초 이상일 때 색을 변환해 준다.
            currentSeconds = '<span style="color:#de1951;">'+currentSeconds+'</span>'
            }
        */
        let dateArr = calendar.split("-");
        let realDate = "";
        for(let i of dateArr){
            if(Number(i) < 10){
                i = "0" + i;
            }
            realDate += i + "-";
        }
        realDate = realDate.slice(0, -1);
        date.innerHTML = realDate;
        clock.innerHTML = currentHours+":"+currentMinute+":"+currentSeconds +" <span style='font-size:50px;'>"+ amPm+"</span>"; //날짜를 출력해 줌

        setTimeout("printClock()",1000);         // 1초마다 printClock() 함수 호출
    }
    // 자릿수 맞춰주기
    function addZeros(num, digit) { // 자릿수 맞춰주기
        let zero = '';
        num = num.toString();
        if (num.length < digit) {
            for (let i = 0; i < digit - num.length; i++) {
                zero += '0';
            }
        }
        return zero + num;
    }

</script>

<script>
    // 사무실A, 사무실B 선택된 식당 목록 페이지 로드
    $(function (){
        $("div.OfficeA").load("./lunch_officeA");
        $("div.OfficeB").load("./lunch_officeB");

        setInterval(function (){
            $("div.OfficeA").load("./lunch_officeA");
            $("div.OfficeB").load("./lunch_officeB");
        },5000);
    });
</script>

<script>
    // 파이차트
    let dataset;
    let labels;
    let datasets;
    let config;
    let canvasOfficeA;
    let canvasOfficeB;
    let pieChart;
    let checkStoreListOfficeA;
    let storeResult;
    let choiceCountARR;
    let choiceStoreARR;
    let bgColor;
</script>

<script>
    $(document).ready(function (){
        // 식당 선택시
       $("div.menu button.store").click(function (){
           if($("div.office input:checked").length == 0){
               // 사무실 미선택
               Swal.fire({
                   title: "사무실을 선택하셨나요?",
                   text: "사무실을 선택하세요!",
                   icon: "warning",//"info,success,warning,error" 중 택1
                   confirmButtonText: "확인"
               });
           }else{
               $(this).siblings('button').removeClass('active');
               $(this).addClass('active');
    
               Swal.fire({
                   title: $(this).val(),
                   text: "선택하시겠습니까?",
                   icon: "info",//"info,success,warning,error" 중 택1
                   showCancelButton: true,
                   confirmButtonColor: '#3085d6',
                   confirmButtonText: '네',
                   cancelButtonColor: '#d33',
                   cancelButtonText: '아니오'
               }).then((result) => {
                   if (result.isConfirmed) {
                       // 식당 선택 동의
                       let StorePickedVO = {
                           "storePicked" : $(this).val(),
                           "office" : $("div.office input:checked").val()
                       }
                       
                       $.ajax({
                           url:"/api/choice",
                           method : "POST",
                           data : JSON.stringify(StorePickedVO),
                           contentType : "application/json",
                           success:function (data) {
                               if (data.result == 'success') {
                                   Swal.fire({
                                       title: "식당 선택 완료",
                                       icon: "success",//"info,success,warning,error" 중 택1
                                       confirmButtonText: "확인"
                                   }).then((result) => {
                                       if (result.isConfirmed) {
                                           location.reload();
                                       }
                                   });
                               }else {
                                   alert('식당 선택 error')
                               }
                           },
                           error:function(e){
                               alert(e+"\nerror");
                               console.log(e);
                           }
                       });
                   }else{
                       // 식당 선택 거절
                       $("div.menu button.store").removeClass('active');
                   }
               });
           }
       });
       
       // 식당 추가 팝업 띄우기
       $("button.addStore").click(function (){
           $("div.popup_bg").css("display","flex");
           $("div.append_store").css("display","block");
       });
    
        // 팝업 닫기
        $("button.btn_cancel").click(function(){
            $("div.append_popup").css("display","none");
            $("div.append_popup form")[0].reset();
            $("div.popup_bg").css("display","none");
        });
    
        // 가격 input
        $("input.input_price").on("keyup", function() {
            $(this).val(addComma($(this).val().replace(/[^0-9]/g,"")));
        });
    
        //천단위마다 콤마 생성
        function addComma(data) {
            return data.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
        }
        
        // 찐 식당 추가 클릭시
        $("button.btn_append").click(function(){
            let store = $("input[name=store]").val();
            if(!store){
                Swal.fire({
                    text: "식당 이름을 입력해주세요.",
                    icon: "warning",//"info,success,warning,error" 중 택1
                    confirmButtonText: "확인"
                });
                return false;
            }else{
                let minimum_price = $("input[name=minimum_price]").val();
                let delivery_tip = $("input[name=delivery_tip]").val();
                let delivery_detail = $("input[name=delivery_detail]").val();
                
                let VO = {
                    "store" : store,
                    "minimum_price" : minimum_price,
                    "delivery_tip" : delivery_tip,
                    "delivery_detail" : delivery_detail,
                }
    
                // ajax 통신하기
                $.ajax({
                    url:"/api/insertNewStore",
                    method : "POST",
                    data : JSON.stringify(VO),
                    contentType : "application/json",
                    success:function (data) {
                        Swal.fire({
                            title: "식당을 추가하였습니다.",
                            icon: "success",//"info,success,warning,error" 중 택1
                            confirmButtonText: "확인"
                        }).then((result) => {
                            location.reload();
                        });
                    },
                    error:function(e){
                        alert(e+"\nerror");
                    }
                });
            }
        });
    });
</script>

</body>
</html>

최초 스토리보드에서 기능 3개만 넣었지만 실제로 만들고 보니 각각 꽤나 걸렸던기억이 든다.

  • 결식 api 통신
  • 식당선택시 유효성검사(사무실선택여부)
  • 팝업창 외부영역클릭 시 팝업 닫기
  • 날짜&시계
  • 10시20분에 페이지 /menu 로 넘기기
  • body에 onload하여 지속
  • 파이차트(원형차트) - 5초마다 새로고침(load된 하부 div안의 페이지)으로 투표현황 팔로우업

이 정도가 있겠다.

  • 파이차트 load된 lunch_officeA.jsp (B랑 코드똑같음)
  •  
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>

<h3>사무실A</h3>
<c:choose>
	<c:when test="${StoreListOfficeA eq null || empty StoreListOfficeA}">
		<div class="nonStore">선택된 식당이 없습니다.</div>
	</c:when>
	<c:otherwise>
		<ul class="chosenStoreList">
			<c:forEach var="chosenStore" items="${StoreListOfficeA}">
				<li>
					<dl>
						<dt>이름</dt>
						<dd>${chosenStore.id}</dd>
					</dl>
					<dl>
						<dt>식당</dt>
						<dd>${chosenStore.storePicked}</dd>
					</dl>
				</li>
			</c:forEach>
		</ul>
		
		<div class="pie-chart">
			<canvas id="canvasOfficeA" width="400" height="400"></canvas>
		</div><%--.pie-chart--%>
		
		<script>
			// 파이차트 구현
			checkStoreListOfficeA = [];
      <c:forEach var="chosenStore" items="${StoreListOfficeA}">
				checkStoreListOfficeA.push("${chosenStore.storePicked}");
			</c:forEach>

			storeResult = {};
			
      checkStoreListOfficeA.forEach((index) => {
        storeResult[index] = (storeResult[index] || 0)+1;
      });
			
      storeResult = JSON.stringify(storeResult);
      storeResult = storeResult.slice(0, -1);
      storeResult = storeResult.substr(1);
      storeResult = storeResult.split(",");

      choiceCountARR = [];
      choiceStoreARR = [];
      storeResult.forEach((item, index) => {
        let itemArr = item.split(":");
        choiceCountARR.push(Number(itemArr[itemArr.length - 1]));
        choiceStoreARR.push(itemArr[0].slice(0, -1).substr(1));
      });
      
      bgColor = ['#F44336','#29B6F6','#FFEE58','#8D6E63','#FF7043','#FFA726','#263238','#3949AB'];
			
      dataset = {
        label: "식당 선택률",
	      backgroundColor: bgColor,//라벨별 컬러설정
	      data: choiceCountARR
      }
      labels=choiceStoreARR;
      datasets={ datasets:[dataset], labels:labels }
			console.log(dataset);

      config = {
        type: 'pie',
	      data: datasets, //데이터 셋
	      animation:false,
				options: {
          responsive: true,
					maintainAspectRatio: false, //true 하게 되면 캔버스 width,height에 따라 리사이징된다.
					legend: {
            position: 'bottom',
						fontColor: 'black',
						align: 'center',
						display: true,
						fullWidth: true,
						labels: {
              fontColor: 'rgb(0, 0, 0)'
            }
          },
					plugins: {
            labels: [
              {
                render: 'label',
	              fontSize:'15',
                fontStyle: 'bold',
	              position:'outside'
              },
              {
                render: function (args) {
                  return args.value + "표";
                },
                fontSize:'13',
                fontStyle: 'bold',
	              fontColor:'#fff'
                // position:'outside'
              }
            ]
          }
        }
      }

      canvasOfficeA = document.getElementById('canvasOfficeA');
      pieChart = new Chart(canvasOfficeA,config);

		</script>
	</c:otherwise>
</c:choose>

딱히 설명할건없다...


("/menu") - menu.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
	<meta name="viewport" content="user-scalable=0, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, width=device-width" />
	<link href="./css/lunch.css" rel="stylesheet">
	<title>메뉴선택하기</title>
	<script src="http://code.jquery.com/jquery-latest.min.js"></script>
	<script src="//cdn.jsdelivr.net/npm/sweetalert2@11"></script>
</head>
<body onload="printClock()">
	<div id="menu">
		<div class="popup_bg">
			<div class="append_popup append_mainMenu">
				<h3>메인 메뉴 추가<span>?</span><img src="./img/mainMenuExplain.png"></h3>
				<div>
					<form>
						<dl>
							<dt>메인 메뉴 이름</dt>
							<dd><input type="text" name="mainMenu_name" placeholder="메인메뉴 이름을 입력해주세요."></dd>
						</dl>
						<dl>
							<dt>메인 메뉴 가격</dt>
							<dd>
								<input type="text" name="mainMenu_price" class="input_price" placeholder="메인메뉴 가격을 입력해주세요.">원
							</dd>
						</dl>
						<dl>
							<dt>메인 메뉴 설명</dt>
							<dd>
								<input type="text" name="mainMenu_amount" placeholder="메인메뉴 설명을 입력해주세요. (적으면 좋고, 없으면 안적어도 됨)">
							</dd>
						</dl>

					</form>
					<div class="btn_box">
						<button type="button" class="btn_append btn_append_mainMenu">추가</button>
						<button type="button" class="btn_cancel">취소</button>
					</div><%--.btn_box--%>
				</div>
			</div><%--.append_mainMenu--%>
			<div class="append_popup append_subMenu">
				<h3>선택 사항 추가</h3>
				<div>
					<form>
						<dl>
							<dt>선택 사항 제목</dt>
							<dd><input type="text" name="subMenu_title" placeholder="선택사항 제목을 입력해주세요."></dd>
						</dl>
						<dl>
							<dt>선택 사항 종류</dt>
							<dd class="dd_type">
								<div><input type="radio" name="subMenu_type" value="single" id="single"><label for="single">단일 선택</label></div>
								<div><input type="radio" name="subMenu_type" value="multiple" id="multiple"><label for="multiple">다중 선택</label></div>
							</dd>
						</dl>
						<dl>
							<dt>선택 항목 추가<button type="button" class="add_option"><img src="../../img/icon_plus.png"></button></dt>
							<dd>
								<ul>
									<li><input type="text" name="subMenu_name[]" placeholder="이름을 입력해주세요."><input type="text" name="subMenu_option_price[]" class="input_price" placeholder="가격을 입력해주세요.">원</li>
									<li><input type="text" name="subMenu_name[]" placeholder="이름을 입력해주세요."><input type="text" name="subMenu_option_price[]" class="input_price" placeholder="가격을 입력해주세요.">원<button class="btn_remove">ㅡ</button></li>
								</ul>
							</dd>
						</dl>
					</form>
					<div class="btn_box">
						<button type="button" class="btn_append btn_append_subMenu">추가</button>
						<button type="button" class="btn_cancel">취소</button>
					</div><%--.btn_box--%>
				</div>
			</div><%--.append_subMenu--%>
			<div class="append_popup append_addMenu">
				<h3>추가 메뉴 추가</h3>
				<div>
					<form>
						<dl>
							<dt>추가메뉴 이름</dt>
							<dd><input type="text" name="addMenu_name" placeholder="추가메뉴 이름을 입력해주세요."></dd>
						</dl>
						<dl>
							<dt>추가 메뉴 가격</dt>
							<dd>
								<input type="text" name="addMenu_price" class="input_price" placeholder="추가메뉴 가격을 입력해주세요.">원
							</dd>
						</dl>
					
					</form>
					<div class="btn_box">
						<button type="button" class="btn_append btn_append_addMenu">추가</button>
						<button type="button" class="btn_cancel">취소</button>
					</div><%--.btn_box--%>
				</div>
			</div><%--.append_mainMenu--%>
		</div><%--.popup_bg--%>
		
		<div class="dateAndTime">
			<div id="date"></div>
			<div id="clock"></div>
			<div class="lunchCountBox">
				<button>
					식사 인원 현황
				</button>
				<div>

				</div>
			</div><%--.lunchCountBox--%>
		</div><%--.dateAndTime--%>
		
		<div class="menu_container">
			<section class="office_section">
				<input type="radio" name="office" id="사무실A" value="OfficeA"><label for="사무실A" class="office">사무실A<span class="${OfficeAStore}"><input type="hidden" value="">${OfficeAStore}</span></label>
				<input type="radio" name="office" id="사무실B" value="OfficeB"><label for="사무실B" class="office">사무실B<span class="${OfficeBStore}"><input type="hidden" value="">${OfficeBStore}</span></label>
			</section><%--.office_section--%>
			
			<section class="menu_section mainMenu_section">
				<div class="black_bg"></div><%--.black_bg--%>
				<dl>
					<dt>
						메인메뉴
						<button class="appendBtn mainMenu" type="button">추가</button>
					</dt>
					<dd>
						<div>
							<div class="non_menu">메뉴가 없습니다.</div>
							<%--메인메뉴 리스트 뿌려주기--%>
						</div>
					</dd>
				</dl>
			</section><%--.menu_section--%>
			
			<section class="menu_section subMenu_section">
				<div>
					<dl class="subMenu_dl">
						<dt>
							선택 사항
							<span>선택사항을 입력해주세요.</span>
						</dt>
						<dd>
							<textarea name="options"></textarea>
						</dd>
					</dl>
					<dl class="addMenu_dl">
						<dt>
							추가메뉴
							<span>추가메뉴를 입력해주세요.</span>
						</dt>
						<dd>
							<textarea name="addMenu"></textarea>
						</dd>
					</dl>
				</div>
				
				<div class="btn_box">
					<button type="button" class="btn_order">주문</button>
				</div>
			</section><%--.subMenu_section--%>

			<section class="myOrder_section">
			
			</section>
			
			<section class="orderList_section">
				<h2>주문내역</h2>
			</section><%--.orderList_section--%>
		</div><%--.menu_container--%>
		
	</div><%--#menu--%>
	
	<script>
    /* 날짜 및 시계  */
    function printClock() {  /* 시계  */
      let date = document.getElementById("date");
      let clock = document.getElementById("clock");  // 출력할 장소 선택
      let currentDate = new Date();  // 현재시간
      let calendar = currentDate.getFullYear() + "-" + (currentDate.getMonth() + 1) + "-" + currentDate.getDate(); // 현재 날짜
      let amPm = 'AM'; // 초기값 AM
      let currentHours = addZeros(currentDate.getHours(), 2);
      let currentMinute = addZeros(currentDate.getMinutes(), 2);
      let currentSeconds = addZeros(currentDate.getSeconds(), 2);

      if(currentHours >= 12){ // 시간이 12보다 클 때 PM으로 세팅, 12를 빼줌
        amPm = 'PM';
        // currentHours = addZeros(currentHours - 12,2);
      }

      let dateArr = calendar.split("-");
      let realDate = "";
      for(let i of dateArr){
        if(Number(i) < 10){
          i = "0" + i;
        }
        realDate += i + "-";
      }
      realDate = realDate.slice(0, -1);
      date.innerHTML = realDate;
      clock.innerHTML = currentHours+":"+currentMinute+":"+currentSeconds +" <span style='font-size:50px;'>"+ amPm+"</span>"; //날짜를 출력해 줌

      setTimeout("printClock()",1000);         // 1초마다 printClock() 함수 호출
    }

    // 자릿수 맞춰주기
    function addZeros(num, digit) { // 자릿수 맞춰주기
      let zero = '';
      num = num.toString();
      if (num.length < digit) {
        for (let i = 0; i < digit - num.length; i++) {
          zero += '0';
        }
      }
      return zero + num;
    }
	
	</script>
	<script>
    
    $(document).ready(function(){
      $("div.menu_container section.myOrder_section").load("./myOrderList?");
      
	    // 사무실 선택시 메뉴 뿌려주기
	    $.fn.subMenuLoad = function (){
        $("section.mainMenu_section ul li").on('click', function (){
          $(this).addClass('active').siblings().removeClass('active');
        });
	    }

      $('input[name="office"]').change(function() {
        $("section.mainMenu_section dd div").load("./mainMenuList?office="+$(this).val(), function (){
          // 메인메뉴 선택시
          $.fn.subMenuLoad();
          return false;
        });
        $("section.orderList_section").load("./orderList?office="+$(this).val());
      });

      // 가격 input
      $("input.input_price").on("keyup", function() {
        $(this).val(addComma($(this).val().replace(/[^0-9]/g,"")));
      });

      //천단위마다 콤마 생성
      function addComma(data) {
        return data.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
      }
      
      // 메뉴 추가 팝업 띄우기
	    $("button.appendBtn").click(function (){
        if($('input[name=office]:checked').length == 0){
          // 식당(사무실) 미선택시
          Swal.fire({
            title: "식당(사무실)을 선택해주세요.",
            icon: "warning",//"info,success,warning,error" 중 택1
            confirmButtonText: "확인"
          });
          return false;
        }else if($('input[name=office]:checked').length == 1){
          let popup_bg = $("div.popup_bg");
          let mainMenu_popup = $("div.append_mainMenu");
          let subMenu_popup = $("div.append_subMenu");
          let append_addMenu = $("div.append_addMenu");

          popup_bg.css("display", "flex");
          
          if($(this).hasClass("mainMenu")){
            mainMenu_popup.css("display", "block");
          }else if($(this).hasClass("subMenu")){
            subMenu_popup.css("display", "block");
          }else if($(this).hasClass("addMenu")){
            append_addMenu.css("display", "block");
          }
        }
	    });
      
      // 팝업 닫기
      $("button.btn_cancel").click(function(){
        $("div.append_popup").css("display","none");
        $("div.append_popup form")[0].reset();
        $("div.popup_bg").css("display","none");
      });

	    // 메뉴 추가하기
	    $("button.btn_append").click(function(){
        let VO;
        let url;
        let swal;
		    
        // 메인 메뉴 추가할때
        let mainMenuName = $('input[name="mainMenu_name"]').val();
        let mainMenuPrice = $('input[name="mainMenu_price"]').val().replace(",","");
        let mainMenuAmount = $('input[name=mainMenu_amount]').val();
        let store = $('input[name=store]').val();
        if(!mainMenuName){
          Swal.fire({
            text: "메인 메뉴 이름을 입력해주세요.",
            icon: "warning",//"info,success,warning,error" 중 택1
            confirmButtonText: "확인"
          });
          return false;
        }
        if(!mainMenuPrice){
          Swal.fire({
            text: "메인 메뉴 가격을 입력해주세요.",
            icon: "warning",//"info,success,warning,error" 중 택1
            confirmButtonText: "확인"
          });
          return false;
        }
				
        url = "/api/insertMainMenu";
        VO = {
          "store" : store,
          "menu" : mainMenuName,
          "price" : mainMenuPrice,
          "info" : mainMenuAmount
        }
        
        console.log(VO);
        
        office = $("section.office_section input:checked").val();
        swal = function (seq){
          Swal.fire({
            title: "메인 메뉴 추가 완료",
            icon: "success",//"info,success,warning,error" 중 택1
            confirmButtonText: "확인"
          }).then((result) => {
            if (result.isConfirmed) {
              $("#menu div.popup_bg").css("display","none");
              $("div.append_mainMenu").css("display","none");
              $("section.mainMenu_section dd div").load("./mainMenuList?office="+$("section.office_section input[name=office]:checked").val(), function (){
                $("section.mainMenu_section ul li").click( function (){
									// 사무실 선택시 메뉴 뿌려주기
                  $('input[name="office"]').change(function() {
                    $("section.mainMenu_section dd div").load("./mainMenuList?office="+$(this).val(), function (){
                      // 메인메뉴 선택시
                      $.fn.subMenuLoad = function (){
                        $("section.mainMenu_section ul li").on('click', function (){
                          $("section.subMenu_section dl.subMenu_dl dd").load("./subMenuList?menu_seq="+$(this).prop('class'));
                          $("section.subMenu_section dl.addMenu_dl dd").load("./addMenuList?menu_seq="+$(this).prop('class'));
                          $(this).addClass('active').siblings().removeClass('active');
                        });
                      }

                      $.fn.subMenuLoad();
                      return false;
                    });
                  });
                });
                
                $("section.mainMenu_section ul li." + seq).addClass('active');
                $("section.mainMenu_section ul").animate({
                  scrollTop: $("section.mainMenu_section ul").prop('scrollHeight')
                },500);
              });
            }
          });
        }

        // ajax 통신하기
        $.ajax({
          url:url,
          method : "POST",
          data : JSON.stringify(VO),
          contentType : "application/json",
          success:function (data) {
            if(Number(data.result) > 0 ){
              swal(Number(data.result));
            }
            // if (data.result == 'success') {
            //   swal();
            // }else if(data.result == success){
            //   alert('문자열아이다잉')
            // }else {
            //   alert('식당 선택 error')
            // }
          },
          error:function(e){
            alert(e+"\nerror");
          }
        });
	    });
      
      $("div.append_mainMenu h3 span").on("mouseover", function (){
        $("div.append_mainMenu h3 img").css("display","block");
      });
      $("div.append_mainMenu h3 span").on("mouseout", function (){
        $("div.append_mainMenu h3 img").css("display","none");
      });
      
      
      
      // 주문하기 클릭시
      $("button.btn_order").click(function (){
        if($('input[name=office]:checked').length == 0){
          // 식당(사무실) 미선택시
          Swal.fire({
            title: "식당(사무실)을 선택해주세요.",
            icon: "warning",//"info,success,warning,error" 중 택1
            confirmButtonText: "확인"
          });
          return false;
        }else if($('input[name=office]:checked').length == 1){
          // 식당(사무실) 선택시
	        if($("section.mainMenu_section ul li.active").length == 0){
            // 메인메뉴 미선택시
            Swal.fire({
              title: "메인메뉴를 선택해주세요.",
              icon: "warning",//"info,success,warning,error" 중 택1
              confirmButtonText: "확인"
            });
            return false;
	        }
        }
        
        let date = new Date();
        let menu_seq = $("section.mainMenu_section ul li.active input").val();
        let office = $("section.office_section input:checked").val();
        let store = $("section.office_section input:checked").next().children("span").attr("class");
        let menu_name = $("section.mainMenu_section ul li.active span.menu_name").text();
        let options = $("textarea[name=options]").val();
        let addMenu = $("textarea[name=addMenu]").val();
				let price = $("")
        let url = "/api/insertChoiceMenu";
        let VO = {
          "menu_seq" : menu_seq,
	        "office" : office,
          "id" : 	"${id}",
	        "store" : store,
          "menu" : menu_name,
          "menu_option" : options,
          "addmenu" : addMenu,
        }
	      
        console.log(VO);
        
        // ajax 통신하기
        $.ajax({
          url:url,
          method : "POST",
          data : JSON.stringify(VO),
          contentType : "application/json",
          success:function (data) {

              if(data.result == 'success'){
                Swal.fire({
                  title: "주문을 완료하였습니다.",
                  icon: "success",//"info,success,warning,error" 중 택1
                  confirmButtonText: "확인"
                }).then((result) => {
                  $("section.myOrder_section").load("./myOrderList");
                  $("section.orderList_section").load("./orderList?office="+office);
                  $("textarea[name=options]").val('');
                  $("textarea[name=addMenu]").val('');
                  $("#menu .menu_container > section.menu_section dl dd ul li.active").removeClass("active");
                });
              }
              

          },
          error:function(e){
            alert(e+"\nerror");
          }
        });
        
      });
      
      // 식사 현황 가져오기
	    $("div.lunchCountBox button").click(function (){
        $("div.lunchCountBox div").toggle(function (){
          $("div.lunchCountBox div").load("./lunchCount");
        });
	    });
    });
    
	</script>
</body>
</html>

* 페이지기능

  • 날짜&시계 (1초마다 로드되면서 시간이 바뀜)
  • 메뉴추가
  • 메뉴추가 후 자동선택 됨
  • 메뉴추가 후 자동선택시 스크롤생긴다면 제일하단으로 가기때문에 스크롤도 같이 움직임
  • 메뉴-선택사항-추가메뉴 → 주문
  • 나의 주문에서 주문 삭제
  • 사무실별 전체 주문정보 볼수있음
    (메뉴 - 선택사항 순으로 오름차순 정렬 하여 주문할때 같은메뉴들 보기편하게)
  • 식사현황 마우스오버로 볼수있음 - 모든인원 결식 or 주문완료하였는지 체크후 실제 주문

* menu에 load된 jsp페이지들

  • addMenuList.jsp
  • lunchCount.jsp
  • mainMenuList.jsp
  • myOrderList.jsp
  • orderList.jsp
  • subMenuList.jsp(미사용 4편에보면 왜 안쓰는지나옴)

 

GitHub - MasonBaek/springboot_PickingLunchMenu

Contribute to MasonBaek/springboot_PickingLunchMenu development by creating an account on GitHub.

github.com

  • 특이사항
  • menu 페이지만 반응형(?)이라하기에는 허접하지만 모자란실력으로 대충만들어봤다.
  • index.css , lunch.css 2개이다.