4주차 과제를 작성했다.
확실히 직접 하나부터 열까지 건드리니까 그래도 좀 알것 같다.
아직 연습이 더 필요하겠지만, GET과 POST를 사용하는 방식을 그나마 더 익힐 수 있었다.
기존에 만들었던 쇼핑몰 html 파일을 사용하는데 예상치 못한 문제가 있었다. 전에 변형해서 만든다고 수량 만드는 칸을 단순 input이 아니라 select 태그를 사용해서 선다형으로 만든 것. 그랬더니 연습했던 프론트-서버 코딩을 그대로 가져와서는 작동이 되지 않았다. 머리를 싸매며 열심히 구글링한 결과 답을 찾았다!
JQuery의 .val()에 대한 개괄적인 설명 사이트를 찾았다.
JQuery / Method / .val()
여기서 내가 직면한 문제에 적용할 수 있는 부분은 바로
select요소의 value값을 넣으려면
let number = $('select#number').val()
그냥 '#값'이 아니라 'select#값'을 넣어야 한다는 것.
그냥 쓰면 input값이 기본인데, 선택지 값에는 적용이 안되어서 먹통된다.
완성한 코드 기록용
<app.py>
from flask import Flask, render_template, jsonify, request
app = Flask(__name__)
from pymongo import MongoClient
client = MongoClient('localhost', 27017)
db = client.dbhomework
## HTML 화면 보여주기
@app.route('/')
def homework():
return render_template('index.html')
# 주문하기(POST) API
@app.route('/order', methods=['POST'])
def save_order():
name_receive = request.form['name_give']
number_receive = request.form['number_give']
address_receive = request.form['address_give']
phone_receive = request.form['phone_give']
doc = {
'name': name_receive,
'number': number_receive,
'address': address_receive,
'phone': phone_receive,
}
db.orderhpbot.insert_one(doc)
return jsonify({'msg1': '주문이 완료되었습니다.', 'msg2': '더 많은 기종의 헬퍼봇들이 궁금하다면? 뮤지컬 [어쩌면 해피엔딩]을 보러 오세요! (~2021년 9월 5일까지)'})
# 주문 목록보기(Read) API
@app.route('/order', methods=['GET'])
def view_orders():
orders = list(db.orderhpbot.find({}, {'_id': False})) # 고를 필요 없으니 중괄호 안은 비워도 됨 (다 가져옴!)
return jsonify({'all_orders': orders})
if __name__ == '__main__':
app.run('0.0.0.0', port=5000, debug=True)
<index.html>
<!doctype html>
<html lang="en">
<head>
<!-- Required meta tags -->
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<!-- Bootstrap CSS -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css"
integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">
<!-- Optional JavaScript -->
<!-- jQuery first, then Popper.js, then Bootstrap JS -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js"
integrity="sha384-ApNbgh9B+Y1QKtv3Rn7W3mgPxhU9K/ScQsAP7hUibX39j7fakFPskvXusvfa0b4Q"
crossorigin="anonymous"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js"
integrity="sha384-JZR6Spejh4U02d8jOt6vLEHfe/JQGiRRSQQxSfFWpi1MquVdAyjUar5+76PVCmYl"
crossorigin="anonymous"></script>
<title>HELPER BOT 5 for sale - Mini Ed.</title>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Noto+Serif+KR:wght@200&display=swap" rel="stylesheet">
<style>
* {
font-family: 'Noto Serif KR', serif;
}
</style>
<script>
$(document).ready(function () {
showOrder();
q1();
});
function q1() {
$('#wontodollar').empty()
$.ajax({
type: "GET",
url: "http://spartacodingclub.shop/sparta_api/rate",
data: {},
success: function (response) {
let rate = response['rate']
console.log(rate)
$('#wontodollar').append(rate)
}
})
}
function makeOrder() {
let name = $('#name').val()
let number = $('select#number').val()
let address = $('#address').val()
let phone = $('#phone').val()
$.ajax({
type: "POST",
url: "/order",
data: {name_give: name, number_give: number, address_give: address, phone_give: phone},
success: function (response) {
alert(response["msg1"]);
alert(response["msg2"])
window.location.reload();
}
})
}
function showOrder() {
$.ajax({
type: "GET",
url: "/order",
data: {},
success: function (response) {
let orders = response['all_orders']
for (let i = 0; i < orders.length; i++) {
let name = orders[i]['name']
let number = orders[i]['number']
let address = orders[i]['address']
let phone = orders[i]['phone']
let temp_html = `<tr>
<td>${name}</td>
<td>${number}</td>
<td>${address}</td>
<td>${phone}</td>
</tr>`
$('#orders-box').append(temp_html)
}
}
})
}
</script>
<style>
.wrap {
background-image: linear-gradient(to left, #a8edea 0%, #fed6e3 60%);
width: 500px;
margin: auto;
}
.imgplace {
width: 500px;
height: 700px;
overflow: hidden;
}
.selltitle {
text-align: center;
margin-bottom: 20px;
}
.btn {
font-size: 15px;
}
.subbtn {
margin: auto;
display: block;
}
.title {
color: white;
}
.title2 {
text-shadow: 1px 1px 5px #000;
font-size: 40px;
font-weight: bolder;
}
.price {
font-size: 15px;
color: black;
}
.label-middle {
padding-left: 20px;
padding-right: 20px;
}
.wrap2 {
margin-top: 15px;
}
.rating {
font-weight: bold;
color: #b490ca;
text-shadow: -2px 0 white,
0 2px white,
2px 0 white,
0 -2px white;
}
.orderlist {
margin-top: 60px;
color: black;
background-color: white;
opacity: 50%;
}
</style>
</head>
<body>
<div class="wrap">
<div id="carouselExampleIndicators" class="carousel slide imgplace" data-ride="carousel">
<ol class="carousel-indicators">
<li data-target="#carouselExampleIndicators" data-slide-to="0" class="active"></li>
<li data-target="#carouselExampleIndicators" data-slide-to="1"></li>
<li data-target="#carouselExampleIndicators" data-slide-to="2"></li>
</ol>
<div class="carousel-inner">
<div class="carousel-item active">
<img class="d-block w-100 " src="https://pbs.twimg.com/media/E4bQUALXEAAM2v7?format=jpg&name=large"
alt="First slide">
</div>
<div class="carousel-item">
<img class="d-block w-100 " src="https://pbs.twimg.com/media/E0qkCnrUcAEgVOx?format=jpg&name=large"
alt="Second slide">
</div>
<div class="carousel-item">
<img class="d-block w-100 photo "
src="https://pbs.twimg.com/media/E5ZKNFvUcAA9yB4?format=jpg&name=large"
alt="Third slide">
</div>
</div>
<a class="carousel-control-prev" href="#carouselExampleIndicators" role="button" data-slide="prev">
<span class="carousel-control-prev-icon" aria-hidden="true"></span>
<span class="sr-only">Previous</span>
</a>
<a class="carousel-control-next" href="#carouselExampleIndicators" role="button" data-slide="next">
<span class="carousel-control-next-icon" aria-hidden="true"></span>
<span class="sr-only">Next</span>
</a>
</div>
<div class="wrap2">
<div>
</div>
<div class="selltitle">
<h1 class="title">
<a class="title2">
중고 헬퍼봇 팝니다
</a>
<span class="price">
<i>가격: 66000원/체</i>
</span>
</h1>
</div>
<p>
기종: HELPER BOT 5 - Mini edition <br>
신품 구매날짜: 2021년 6월 29일 <br>
사이즈: XL <br>
컬러코드: SKYBLUE-ORANGE <br>
</p>
<h6 class="rating"> 달러 - 원 환율: <span id="wontodollar"> </span></h6>
<p class="selltitle">
헬퍼봇에 대해 더 자세한 정보가 필요해요 ▶ <a href="https://tickets.interpark.com/goods/21003923" class="btn btn-secondary"
role="button" aria-pressed="true">여기를 눌러 보세요</a>
</p>
<div class="input-group mb-3">
<div class="input-group-prepend">
<span class="input-group-text" id="basic-addon1">주문자 성함</span>
</div>
<input type="text" class="form-control" aria-label="주문자 성함 입력칸"
aria-describedby="basic-addon1" id="name">
</div>
<div class="input-group mb-3">
<div class="input-group-prepend">
<label class="input-group-text label-middle" for="number">주문 수량</label>
</div>
<select class="custom-select" id="number">
<option selected>--수량을 선택해 주세요--</option>
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
<option value="4">4</option>
</select>
</div>
<div class="input-group mb-3">
<div class="input-group-prepend">
<span class="input-group-text label-middle" id="basic-addon1">배송 주소</span>
</div>
<input type="text" class="form-control" aria-label="주소 입력칸"
aria-describedby="basic-addon1" id="address">
</div>
<div class="input-group mb-3">
<div class="input-group-prepend">
<span class="input-group-text" id="basic-addon1">핸드폰 번호</span>
</div>
<input type="text" class="form-control" placeholder="예) 010-1234-5678" aria-label="전화번호 입력칸"
aria-describedby="basic-addon1" id="phone">
</div>
<p>
<a onclick="makeOrder()">
<button class="btn btn-secondary subbtn"> 구매하기</button>
</a>
</p>
</div>
<div class="orderlist">
<table class="table">
<thead>
<tr>
<th scope="col">주문자 성함</th>
<th scope="col">주문 수량</th>
<th scope="col">배송 주소</th>
<th scope="col">핸드폰 번호</th>
</tr>
</thead>
<tbody id="orders-box">
</tbody>
</table>
</div>
</body>
</html>
팀프로젝트는 오늘 2차 튜터 질문 시간을 가졌고, 팀 조원 중 한 명이 사이드바를 만드는 것을 제안해서 적용했다. display flex는 다들 시도해봤는데 생각보다 잘 되지 않았다.
아무래도 진도와 병행하려니 다른 조원들에 비해 내 참여율이 저조해서 마음이 좋지 않다. ㅠ