웹프로그램에서 form 태그 안의 사용자 입력 태그들의 name과 value를 서버로 보낼 때
그냥 form 태그 객체의 submit 으로 보낼 때는 상관없는뎅,이것들을 AJAX로 보내야 할 때,
form태그안에 사용자 입력태그(input:text 등등)가 꽤나 많다면 이것들을 일일이 접근해서
name=value&name=value 식의 쿼리스트링으로 만드는 건 여간 귀찮은 일이 아닐 것이당.
(input:text만 만개가 있다고 가정해 보라!~~ 토 나오공 분명 빼먹을거당!)
이럴 때 보통 퀴리스트링으로 만들려면 jQuery의 serialize() 메소드를 사용하고,
JSON 문자열 형태로 만들려면 serializeJSON() 메소드를 사용한당.
jQuery는 자바스크립트로 맹글어졌기 때문에 jQuery로 할 수 있는 건 자바스크립트로
다 할 수 있지만, 그 역은 항상 그렇지만은 않당.
serialize와 serializeJSON을 그냥 사용하는 것도 크게 나쁘지는 않지만, 별로
그리 대다한 내용이 아니니, 직접 한번 만들어 보면, 그 시간이 초롱초롱 반짝할 것 같당!.
serialize 이해에 필요한 핵심은 form 태그 객체의 elements 속성이당.
아래 html 소스를 복사/붙여넣기로 실행해보고, console.log 결과에 느낌 받장!
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<form>
<h3 name="huk">요건 elements에 포함 안되용</h3>
<input type="text" name="samNm" value="e7e"><br>
<input type="text" name="samAge" value="30"><br>
<div name="merong">안 담겨용</div>
<input type="text" name="samAlias" value="cuty"><br>
<input type="button" name="samBtn" value="포함되용">
</form>
<script>
// form태그 객체의 elements 속성에 사용자 입력태그들만 담겨 옴
const elems = document.forms[0].elements;
for (let i = 0; i < elems.length; i++) {
let elem = elems[i];
console.log("체킁", i, elem, elem.name, elem.value);
}
</script>
</body>
</html>
위 샘플 소스에 느낌받았다면 아래 소스도 그냥 이해 될 수 밖에 없당.
복사/붙여넣기로 실행해서 결과와 소스를 눈과 뇌에 매칭시키장!
일부러 주석을 많이 달았으니, 자바스크립트 소스에 주목해서 보도록 하장.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>E7E 만만세</title>
<style>
* {
font-weight: bolder;
}
h1 {
background-color: black;
color: yellowgreen;
}
#disp {
white-space: pre-wrap;
word-wrap: break-word;
border: 1px solid blue;
min-height: 70px;
width: 360px;
overflow: auto;
}
</style>
</head>
<body>
<form>
<table border="1">
<tr>
<td colspan="2">
<h1>Serialize 해봐용</h1>
</td>
</tr>
<tr>
<td>이름</td>
<td><input type="text" name="empName" id="empName" style="width:95%"
pattern="[가-힣]{3,4}"
placeholder="한글3~4자" value="금수저" required></td>
</tr>
<tr>
<td>이메일</td>
<td><input type="text" name="empEmail" id="empEmail"
pattern="[a-z0-9]+@[a-z]+\.[a-z]{2,3}"
style="width:95%" value="ksj@onami.com" required></td>
</tr>
<tr>
<td>성별</td>
<td>
남<input type="radio" name="empSB" id="empSB" value="male">
여<input type="radio" name="empSB" id="empSB" value="femail" checked>
</td>
</tr>
<tr>
<td>역할</td>
<td>
<select name="empRole" id="empRole">
<option value="si">개발[SI]</option>
<option value="sm">유지보수[SM]</option>
<option value="mg" selected>매니저[총괄]</option>
</select>
</td>
</tr>
<tr>
<td>능력</td>
<td>
프론트<input type="checkbox" name="empScope" id="empScope" value="front">
백엔드<input type="checkbox" name="empScope" id="empScope" value="backend">
D B<input type="checkbox" name="empScope" id="empScope" value="db">
메롱<input type="checkbox" name="empScope" id="empScope" value="merong">
</td>
</tr>
<tr>
<td>간략자기소개</td>
<td><textarea name="empAbout" id="empAbout" cols="30" rows="10" required></textarea></td>
</tr>
<tr>
<td colspan="2" style="text-align: center;">
<input type="submit" name="serBtn" id="serBtn" value="serialize">
<input type="submit" name="jsonBtn" id="jsonBtn" value="serializeJSON">
</td>
</tr>
<tr>
<td colspan="2">
<pre id="disp">
</pre>
</td>
</tr>
</table>
</form>
<script>
/************** 임시 대책부 ***************/
//textarea에 직접 값 넣으면 htmlㅅ소스가 안 예쁨
document.querySelector("#empAbout").value = "안농 난 E7E라고 행\n아프로 뒤로 잘 지내보장";
/************** 전역변수 객체 선언부 ***************/
const empForm = document.forms[0]; // form태그가 1개 밖에 없으니깡!
// console.log로 찍었을 때, ...List, ...Collection이라고 나오는 것은
// 유사배열이라고 해서, 배열의 메소드를 사용하려면 배열로 변환해야 함!
const formElems = Array.from(empForm.elements);
const justDisp = document.querySelector("#disp");
// submit 버튼을 2개 넣었음!(일부렁)
const submitBtns = Array.from(document.querySelectorAll("input[type=submit]"));
let whichBtn = ""; // 어느 submit 버튼을 눌렀는가? 저장변수 serBtn Or jsonBtn
/************** 전역함수 선언부 ***************/
// 시리얼라이즈 하기 전에 의미없는 element 제거
// 곧 서버로 전달할 필요가 없는 값! 예를 들면 체크 안된 체크박스의 값
// 시리얼라이즈, JSON문자열화 양쪽에 필요해서 별도 함수로 추출
const preRemoveElem = () => {
// 배열의 filter 메소드를 이용하여 제거
let selElems = formElems.filter(elem => {
if (elem.type == "button" || elem.type == "submit" || elem.type == "reset") {
return false; // 제거 하겠다는 의미
}
if ((elem.type == "radio" || elem.type == "checkbox") && !elem.checked) {
return false;
}
return true; // 담겠다는 의미
});
return selElems;
}
// 시리얼라이즈 함수!, 여기서의 의미는 쿼리스트링 형태
// name=금수저&initial=ksj&age=23 형태의 문자열
const fFormSerialize = () => {
let serializeStr = ""; // 시리얼라이즈 결과 담을 변수
// 필요없는 거 먼저 제거 후, 시리얼라이즈
preRemoveElem().forEach(elem => {
serializeStr += `${elem.name}=${elem.value}&`;
});
serializeStr = serializeStr.substr(0, serializeStr.length - 1);// 마지막 & 제거
console.log("시리얼 디버깅:", serializeStr);
justDisp.innerText = serializeStr; // 화면에 뿌리깅
return serializeStr;
}
const fFormSerializeJSON = () => {
//필요없는 거 먼저 제거 후, JSON화
let jsonObj = {}; // 빈 객체
let arrForCheck = []; // 체크된 체크박스값 담을 빈 배열
preRemoveElem().forEach(elem => {
if (elem.type == "checkbox") {
arrForCheck.push(elem.value);
jsonObj[elem.name] = arrForCheck; // 배열식 접근법 이용
return;
}
// 배열식 접근법 이용 객체에 속성:값 형태 추가
jsonObj[elem.name] = elem.value;
})
console.log("JSON 디버깅:", jsonObj);
let jsonStr = JSON.stringify(jsonObj);
justDisp.innerText = jsonStr;
return jsonStr;
}
// submit 버튼을 클릭하면, form객체에 전송 직전에 submit이벤트 발생
const fSubmit = () => {
event.preventDefault(); // form 전송(submit) 막깅
if (whichBtn == "serBtn") {
alert("시리얼라이즈 누르셨어용");
alert(fFormSerialize()); // Form의 element serialize
} else {
alert("JSON 누르셨어용");
alert(fFormSerializeJSON()); // Form의 element serialize json
}
}
// submit 버튼을 클릭하면, 버튼 id를 전역변수에 저장
const fWhichBtn = () => {
whichBtn = event.target.id;
}
/************** 이벤트 등록부(바인딩) ***************/
// form submit이벤트 발생시 fSubmit 호출
empForm.addEventListener("submit", fSubmit)
// submit 버튼 클릭시 fWhichBttn 호출
submitBtns.forEach(btn => {
btn.addEventListener("click", fWhichBtn)
});
</script>
</body>
</html>
혹 소스 기럭지가 길어 거부감이 생기지 않을까 시퍼
뽀인또를 쪼금 설명하면 , 사용자 입력태그가 아닌 것(h1,div등등)은 알아서 걸러주므로,
신경 쓸 것이 없는뎅, 문제는 button 태그등의 name,value값은 서버에 보낼 필요가 없고,
radio는 체크된 값만 보내야 하며, checkbox는 여러개가 체크 될 수 있으므로,
JSON문자열로 만들 때 value들을 배열에 담고, 속성명은 name에 담으면 , 서버쪽에서
받기가 편할 것이당.
이 부분을 배열의 filter메소드를 이용해서, submit 버튼과 체크 안된 radio, checkbox등을
미리 걸러낸 다음에 forEach를 이용하여, serialize나 serializeJSON을 진행하였당.
이 생각을 담고 본다면, 소스의 핵심만 느낌있게 보일거시당.(당신 자신을 믿어랑!)
잘 이해가 되었다면, 당신은 JSON의 배열식 접근법이 얼마나 편한지 느꼈을거공,
아프론 데이타 구조 변화가 당신 손에서 마구 자유로울 거시당.
추가적으로 Array.from 메소드도 잘 확인해 두고,
배열의 메소드 filter와 forEach도 사용법 확인(callback을 안다면 만들 수 있당) 하고
한번 그냥 for(let i=0; i<리미트; ㅑ++){} 문으로 바꾸는 작업을 해보장
뜻밖에 얻는 것이 분명 있을 거시당.
입장 바꿔 생각해 보라는 글은 가슴에 공감을 남기는데,
입장 바꿔 생각해 보라는 말을 듣는 것은 가슴에 생채기를 남긴다.
탑-다운의 질책을 받는 느낌이당.
정말 입장바꿔서 생각할 수가 있기는 하는 걸까?
친구였었다면, 이해 할 수 있었을까?
난 결국 나르시스트!!!!
https://www.youtube.com/watch?v=z8FS19r1Xo4
외부파일 드래그 앤 드롭2(File Drag and Drop) (2) | 2023.12.19 |
---|---|
외부파일 드래그 앤 드롭1(File Drag and Drop) (3) | 2023.12.18 |
이벤트 동적 바인딩 당신만 몰라용!! (2) | 2023.11.23 |
검색 드롭다운 원리 (Search Drop Down) (4) | 2023.11.06 |
DHTMLX Gantt (1) | 2023.11.03 |