HTML을 기반으로 만든 나 스스로가 웹앱(?)이라 부르는 간단한 초진 작성기를 완료하였다. 차트 입력만을 위해서 실컷 입력만하고 외래를 보다보면, 추후 데이터 수집할 때 2번의 일이 필요하다. 늘 전공의때 이런 일로 힘들었다. 그래서 차트를 작성하면서 데이터베이스로 저장하는 방식에 대해서 늘 고민이 많았다. SQL 에 대해서 공부했지만, 간단한 앱을 만드는데 SQL에 서버 호스팅까지 하려니 이건 배보다 배꼽이 큰 격이었다. 우연히 검색하다가 구글 spreadsheet를 이용하면 간단한 DB처럼 이용할 수 있다는 내용을 보고 언젠가 만들어야지 언젠가 만들어야지 미루다보니 벌써 6개월 정도가 지나버렸다. 드디어 그 작업을 완료하게 되어서, 기록으로 남겨 놓는다.
결과
이번 작업의 목표는 HTML로 제작한 form에 입력된 자료를 DB로 만드는게 목표였다. 구글 spreadsheet를 이용할 예정이었고, 아래 영상에서 잘 나와있다.
다른 몇몇 영상들은 "id=entry_XXXXXXXXXXX"로 되어있어서 작동이 안되는 것 같았고, jquery를 이용하여 ajax로 하는 방법도 있었지만, 이 방법이 가장 간단하여서 택하였다. (사실 ajax를 잘 다루지 못한다...) 동영상에 잘 나와있지만 내용을 간단하게 요약해보면 아래와 같다.
- 구글 form을 이용하여 설문지 form을 만든다. 이 때 항목은 본인의 database schema를 생각해서, 수집할 데이터가 무엇인지를 결정해서 만들면 된다. 나는 "통증부위, 좌우, 외상여부, 외상이유, 통증기간, VAS" 6개의 항목으로 결정하였다. (추후 변경이 가능하다)
- 설문지 form에서 control +shift +I(요소검사)를 해보면 <form 이라는 곳에 보면, url이 나오게 되는데 이 주소가 바로 내가 POST방식으로 쿼리를 보내야할 url이다.
- 아래의 코드는 가장 기본 형식으로 되어있는 내용이다. 요소검사에서 각각에 해당하는 name을 찾아서 form에 name에 입력해주면, form에 입력된 자료는 entry.XXXXXX라는 구글 스프레드시트항목에 입력되게 된다.
실제 적용
하지만, 실제 적용은 역시 쉽지 않았다. 하면서 겪었던 내용들 중 해결한 방법은 아래와 같다.
- name으로 entry.XXXXXXXXXX로 입력하니 parsing이 잘 안되는 항목이 있어서 id와 name 모두를 entry.XXXXXXXX로 변경하였다.
- name이 여러 개인 경우에는, spreadsheet에 저장될 때 ",(comma)"로 구분되며 추가된다. (추후 해결해야함)
- form 을 submit할 때마다 새로운 창이 생기거나 (target="_blank"), 기존의 창에서 변경되게 되어서 (target="_self") target="resultIframe"라는 내용을 입력하였다. ""안에 frame의 "name"을 입력하면 iframe 태그가 있는 곳에서 해당 결과페이지가 iframe 방식으로 열리게 된다.
<!doctype html>
<html>
<head>
<meta charset='UTF-8'><meta name='viewport' content='width=device-width initial-scale=1'>
</head>
<style>
body{
font-family:'Nanum Gothic', sans-serif;
background-image:url('https://source.unsplash.com/user/impatrickt');
background-size:100%;
}
.blank25{
height:25px;
}
.content-wrap{
background-color:white;
margin-left:auto;
margin-right:auto;
width :550px;
border: 3px solid #333333;
padding: 20px;
border-radius:5px;
}
.my-content{
font-size:20px;
line-height:1.8em;
}
.my-range{
font-size:20px;
}
.my-content input[type=radio],.my-content input[type=checkbox]{
/* Double-sized Checkboxes */
-webkit-transform: scale(2); /* Safari and Chrome */
margin: 10px;
}
input[type="button"]{
margin-top:20px;
padding: .5rem 1rem;
font-size: 1.25rem;
line-height: 1.5;
border-radius: .3rem;
color: #fff;
background-color: #007bff;
border-color: #007bff;
width: 300px;
}
input[type="reset"]{
padding: .5rem 1rem;
font-size: 1.25rem;
line-height: 1.5;
border-radius: .3rem;
color: #fff;
}
input[type=range]{
-webkit-appearance: none;
width:250px;
}
input[type=range]::-webkit-slider-thumb {
-webkit-appearance: none;
border: 3px solid white;
height: 20px;
width: 20px;
border-radius: 50%;
background: red;
margin-top: -4px;
}
input[type=range]::-webkit-slider-runnable-track {
width: 500px;
height: 10px;
background: #ddd;
border: none;
border-radius: 3px;
}
input[type=range]:focus {
outline: none;
}
input[type=range]:focus::-webkit-slider-runnable-track {
background: #ccc;
}
input[type="reset"]{
background-color: white;
color: #333333;
}
textarea {
border:2px solid black;
width: 92%;
border-radius:5px;
padding:20px;
font-size:1rem;
font-weight:700;
font-family:'Nanum Gothic', sans-serif;
}
input[type=range]:focus::-webkit-slider-runnable-track {
background: #367ebd;
}
@media screen and (max-width:500px){
.content-wrap{
}
.my-content{
font-size:15px!important;
}
.my-content input[type=radio],.my-content input[type=checkbox]{
/* Double-sized Checkboxes */
-webkit-transform: scale(1.5); /* Safari and Chrome */
margin: 8px;
}
.content-wrap{
width :90%;
padding: 1rem;
border-radius:5px;
}
}
</style>
<script>
function myFunction(){
//오늘 날짜 확인
var date = new Date(); //매개변수가 없는 경우 현재 날짜와 시간을 가지는 인스턴스를 반환한다.
var month = date.getMonth() + 1; // 0부터 시작하므로 1더함 더함
var day = date.getDate();
if (("" + month).length == 1) { month = "0" + month; }
if (("" + day).length == 1) { day = "0" + day; }
var printedDate = month +'-'+day;
<!-- 아래 부분은 통증 위치 파악-->
var Location = ""
for(var i=0; i<19; i++){
if(document.getElementsByName("entry.268954659")[i].checked == true){
var Location = Location + document.getElementsByName("entry.268954659")[i].value
}};
//
//아래 부분은 통증 좌우 파악
var Lesion=""
for(var i=0; i<3; i++){
if(document.getElementsByName("entry.115438232")[i].checked == true){
var Lesion = document.getElementsByName("entry.115438232")[i].value
}};
// 아래 부분은 외상 여부 파악
var Trauma=""
var TraumaReason= document.getElementById("entry.2066414521").value
var TraumaDuration= document.getElementById("entry.838521009").value
for(var i=0; i<2; i++){
if(document.getElementsByName("entry.1861609866")[i].checked == true){
var Trauma = document.getElementsByName("entry.1861609866")[i].value
}};
//아래 부분은 VAS 파악
var VAS=document.getElementById("vas-range").value;
var printedResult= Location +' '+ Lesion+' '+Trauma+' '+TraumaReason+' , '+ TraumaDuration+' , VAS: '+VAS +'\n'+ 'SB(+)'+'\n'+printedDate ;
document.getElementById("myResult").innerHTML= printedResult;
//아래는 결과 트리밍
printedResult=printedResult.replace(' ',' r');
//결과 클립볻드로 복사
copy_to_clipboard();
};
function copy_to_clipboard() {
var copyText = document.getElementById("myResult");
copyText.focus();
copyText.select();
document.execCommand("Copy");
}
</script>
<body>
<div class="blan25"></div>
<div class="content-wrap">
<h1> 초진 기록지 for BM by BM </h1>
<form action="https://docs.google.com/forms/d/e/1FAIpQLSe4nJ1TXTJrVuR8gpM3a5myVxJDyw8DG3ERjTKvgibrUk0Rhg/formResponse"
target="resultIframe" method="POST" >
<div class="my-content">
<div name="my-pain-location">
<input type="checkbox" name="entry.268954659" value="목,">목
<input type="checkbox" name="entry.268954659" value="어깨,">어깨
<input type="checkbox" name="entry.268954659" value="어깨죽지,">어깨죽지
<input type="checkbox" name="entry.268954659" value="허리,">허리
<input type="checkbox" name="entry.268954659" value="등,">등
<input type="checkbox" name="entry.268954659" value="갈비뼈,">갈비뼈 <br>
<input type="checkbox" name="entry.268954659" value="엉덩이,">엉덩이
<input type="checkbox" name="entry.268954659" value="고관절,">고관절
<input type="checkbox" name="entry.268954659" value="허벅지,">허벅지
<input type="checkbox" name="entry.268954659" value="무릎,">무릎
<input type="checkbox" name="entry.268954659" value="종아리,">종아리<br>
<input type="checkbox" name="entry.268954659" value="발목,">발목
<input type="checkbox" name="entry.268954659" value="발가락,">발가락
<input type="checkbox" name="entry.268954659" value="발바닥,">발바닥
<br>
<input type="checkbox" name="entry.268954659" value="손가락,">손가락
<input type="checkbox" name="entry.268954659" value="팔꿈치,">팔꿈치
<input type="checkbox" name="entry.268954659" value="손목,">손목
<input type="checkbox" name="entry.268954659" value="손바닥,">손바닥
<input type="checkbox" name="entry.268954659" value="lower arm,"> lower arm
</div>
<hr>
<div name="my-pain-lesion">
<input type="radio" name="entry.115438232" value="-/+,">좌
<input type="radio" name="entry.115438232" value="+/-,">우
<input type="radio" name="entry.115438232" value="+/+,">양측
</div>
<div name="my-trauma">
<input type="radio" name="entry.1861609866" value="외상(-)" checked>외상 없음
<input type="radio" name="entry.1861609866" value="외상(+):">외상 있음
<input type="text" id="entry.2066414521" name="entry.2066414521" placeholder="이유를 입력하세요" value=""
minlength="1" maxlength="200" size="50" height="30px" style="line-height: 30px;"><br>
<input type="text" id="entry.838521009" name="entry.838521009" placeholder="통증 기간을 입력하세요" value=""
minlength="1" maxlength="200" size="30" height="30px" style="line-height: 30px;">
</div>
<div class="my-range">
VAS <input oninput = 'ShowSliderValue(this.value)' id="vas-range" name="entry.894327154" type = "range" min='0' max='10' value='4' step='2'>
<span id="slider_value_view">4</span>점
<script language = "javascript">
function ShowSliderValue(sVal)
{ var obValueView = document.getElementById("slider_value_view");
obValueView.innerHTML = sVal
}
</script>
</div>
</form>
<div id="submission-hc">
<input type="button" class="btn-yes" value="결과" onclick="myFunction()">
<input type="reset" value="새로고침">
</div>
<div id="result" >
<hr>
<textarea id="myResult" rows="8" style="white-space:pre;">위의 결과를 누르시면 결과가 클립보드로 복사됩니다.</textarea>
<input type="submit" value="DB저장">
<a href="https://docs.google.com/spreadsheets/d/110hSXYRHLGlu5osJQTiGeQ6T48NEtr3pY1kS9pnmzTk/edit?usp=copy" target="_blank" style="text-decoration:none;"> <span style="border:1px solid grey; background-color:#ddd; padding: 2px; font-size:14px;">DB 보기 </span></a>
<iframe name="resultIframe"width="100%" height="50px">iframe</iframe>
</div>
</div>
</body>
</html>
참고 사이트>
1. https://www.youtube.com/watch?v=eVvhNAnOf1A
2. form target="framename"을 이용하여 form의 내용을 submit 하더라도 다른 페이지로 연결되지 않게 하는 법
'보이지 않는 더 넓은 세상💻 > 개발인지 개🐕발인지' 카테고리의 다른 글
구글 스프레드 시트를 DB로 사용하기# 2 (0) | 2019.11.06 |
---|---|
디지털 헬스 해커톤 2019 참가 후기 (2) | 2019.10.16 |
보편적이지 않은 개발] 초진기록지 #2 (0) | 2019.05.15 |
보편적이지 않은 개발#2] 예진 차트 작성기 (0) | 2019.05.10 |
보편적이지 않은 개발] 건강검진 추천 프로그램 #1 (0) | 2019.05.10 |
로그인이 필요없어요.