form 안에 같은 name 의 버튼(radio/checkbox) 값을 구분하기
쇼핑몰을 구현하는 과정을 배우고 있는데, form 내의 같은 이름의 입력란들을 처리하는 과정이 제법 흥미로워 작성해보려고 한다.
1. radio
form 태그에서 radio 버튼을 통해 동의 or 비동의 여부를 받았다. 이때, 각 radio 버튼의 name을 동일하게 주었다.
이후 radio 버튼의 name 을 자바스크립트를 통해 구분짓고, 자바스크립트로 submit 까지 해보려한다.
<section>
<%@ include file="sub_image_menu.jsp" %>
<article>
<form action="shop.do" method="post" name="contract">
<input type="hidden" name="command" value="joinForm"/>
<h2>회원 가입 약관</h2>
<p>언제나 새로운 즐거움이 가득한 Shoes Shop의 회원가입 페이지입니다.<br>
Shoes Shop의 회원가입은 무료이며, 회원님의 개인신상에 관한 정보는
'정보통신망이용촉진 및 정보보호등에관한법률"에 의해 회원님의 동의없이
제 3자에게 제공되지 않으며, 철저히 보호되고 있사오니 안심하고 이용하시기 바랍니다.</p>
<div class="ta"><textarea rows="15">... 약관 전문 ...</textarea></div>
<div class="rb">
<input type="radio" name="okon"> 동의함
<input type="radio" name="okon" checked> 동의안함
</div>
<div class="btn">
<!-- JS로 submit 처리를 할 수 있음 -->
<input type="button" value="Next" onclick="goNext()"/>
</div>
</form>
</article>
</section>
동의안함의 버튼을 누른 채 Next 를 누르면 '회원 약관에 동의하셔야 회원가입이 가능합니다.' 라는 알림창이 뜨고,
동의함 버튼을 눌러야 회원가입 폼으로 넘어가게 된다.
1-2. form 내의 같은 name의 radio
<div class="rb">
<input type="radio" name="okon"> 동의함
<input type="radio" name="okon" checked> 동의안함
</div>
<div class="btn">
<!-- JS로 submit 처리를 할 수 있음 -->
<input type="button" value="Next" onclick="goNext()"/>
</div>
radio 타입의 '동의함', '동의안함' 버튼이 okon 이라는 name 으로 선언되어 있다.
아래에는 'Next' 라는 이름의 버튼이 선언되어 있고, 클릭하면 goNext() 라는 자바스크립트 함수로 이동한다.
1-3. 자바스크립트에서 보는 같은 name의 radio
radio 버튼이 선택되어 있는지 확인하는 방법은 두가지가 있다.
1. 확인하고자하는 radio 버튼에 고유한 id값을 부여하기
ex) document.getElementById(id값).checked == true
2. name 값으로 radio 버튼에 접근하기
ex) document.contract.okon.checked == true
우리가 사용하고자 하는 방법은 2번인데, 만약 name 값이 고유하지 않다면 어떻게 처리해야 하는걸까?
결론부터 말하면 배열로 처리한다. 자바스크립트에서 form 내의 입력란들이 한 개일 때는 단순 변수처럼 활용하지만, 같은 이름일 때는 모두 배열로 인식한다.
/* contract.jsp 에서 약관동의 여부 확인 */
function goNext(){
if(document.contract.okon[1].checked == true){
alert('회원 약관에 동의하셔야 회원가입이 가능합니다');
}else{
document.contract.submit();
}
}
radio 버튼은 checkbox 와 다르게 한가지 값만 체크해 넘길 수 있다. 따라서 값이 몇개 들어왔는지(길이) 등의 값을 따질 필요 없이 form에 입력한 순서대로 okon 배열에 나열되었다고 생각하면 된다.
첫번째에 동의함, 두번째에 비동의 radio 를 만들었다. 따라서 okon[0] 이 동의함, okon[1] 이 비동의다.
값에 접근하기 위한 방식은 아래와 같다.
document.(form의 name).(radio의 name)[index값].checked
html 태그의 요소를 동적으로 수정하기 위한 document 객체안에, form안에, radio가 ' checked ' 상태 를 뜻한다.
2. checkbox
<section>
<%@ include file="../member/sub_image_menu.jsp" %>
<article>
<form name="cartFrm" method="post">
<h2>Cart List</h2>
<c:choose>
<c:when test="${cartList.size()==0}">
<h3>장바구니가 비었습니다.</h3>
</c:when>
<c:otherwise>
<div class="tb">
<div class="row">
<div class="coltitle">상품명</div>
<div class="coltitle">수량</div>
<div class="coltitle">가격</div>
<div class="coltitle">주문일</div>
<div class="coltitle">삭제</div>
</div>
<c:forEach items="${cartList}" var="cartVO">
<div class="row">
<div class="col">${cartVO.pname}</div>
<div class="col">${cartVO.quantity}</div>
<div class="col"><fmt:formatNumber value="${cartVO.price2}" type="currency"/></div>
<div class="col"><fmt:formatDate value="${cartVO.indate}" type="date"/></div>
<div class="col"><input type="checkbox" name="cseq" value="${cartVO.cseq}"/></div>
</div>
</c:forEach>
<div class="row">
<div class="col">총 금액</div>
<div class="col"><fmt:formatNumber value="${totalPrice}" type="currency"/></div>
<div class="col"><a href="#" onclick="go_cart_delete();">삭제하기</a></div>
</div>
</div>
</c:otherwise>
</c:choose>
<div class="btn">
<input type="button" value="쇼핑 계속하기" onclick="location.href='shop.do?command=main'">
<c:if test="${cartList.size() != 0}">
<input type="button" value="주문하기" onclick="go_order_insert()">
</c:if>
</div>
</form>
</article>
</section>
다중 선택이 가능한 checkbox 도 처리해보자.
단, 앞선 상황과 다르게 체크된 값의 개수를 구할 때 활용했다.
2-1. form 내의 같은 name의 checkbox
<c:forEach items="${cartList}" var="cartVO">
<div class="row">
<div class="col">${cartVO.pname}</div>
<div class="col">${cartVO.quantity}</div>
<div class="col"><fmt:formatNumber value="${cartVO.price2}" type="currency"/></div>
<div class="col"><fmt:formatDate value="${cartVO.indate}" type="date"/></div>
<div class="col"><input type="checkbox" name="cseq" value="${cartVO.cseq}"/></div>
</div>
</c:forEach>
EL, JSTL 을 사용해 작성한 코드다.
request 객체에 담은 cartList 를 cartVO 라는 이름으로 하나씩 꺼내내는 반복문 코드다.
반복문이다보니 cartList 에 담긴 객체만큼 checkbox 도 생성될 것이다.
<div class="col"><a href="#" onclick="go_cart_delete();">삭제하기</a></div>
이렇게 생성된 여러개의 checkbox 를 자바스크립트에서 go_cart_delete() 함수로 처리하려고 한다.
2-2. 자바스크립트에서 보는 같은 name의 radio
/* cartList.jsp 장바구니에 담은 항목의 개수 확인 */
function go_cart_delete(){
var count = 0;
// 반복실행문을 이용해서 모든 체크박스를 체크되었는지 검사
for(var i=0; i<document.cartFrm.cseq.length; i++){
if(document.cartFrm.cseq[i].checked == true){
count++;
}
}
if(count == 0){
alert("삭제할 항목을 선택하세요");
}else{
var ans = confirm("선택한 항목을 삭제할까요?");
if(ans){
document.cartFrm.action = "shop.do?command=cartDelete";
document.cartFrm.submit();
}
}
}
사실 radio 와 마찬가지로 checkbox 도 form 내의 입력란 중 하나기 때문에 처리 방식은 같다.
document.(form의 name).(checkbox의 name)[index값].checked
checkbox 는 다중 선택을 할 수 있어 모든 체크박스가 체크되었는지 for문을 통해 확인 해야한다.
2-3. form의 입력값의 개수를 검사하는 length
var count = 0;
// 체크된 체크박스의 개수를 카운트
if(document.cartFrm.cseq.length == undefined){
// 한 개의 체크박스가 체크되었는지만 검사
if(document.cartFrm.cseq.checked == true){
count++;
}
}else{
// 반복실행문을 이용해서 모든 체크박스를 체크되었는지 검사
for(var i=0; i<document.cartFrm.cseq.length; i++){
if(document.cartFrm.cseq[i].checked == true){
count++;
}
}
}
이전에 checkbox 가 한개인지, 두개 이상인지 구분하기 위해 length 라는 상태를 사용했다. checkbox 가 두개 이상 선택된 상태라면 length 는 선택된 개수만큼의 값을 갖게 되지만, 한 개만 선택된 상태라면 length 는 undefined 가 되는 것을 노리고 작성했다.
그러나 사실 length는 checkbox 의 개수만 출력할 뿐, 체크된 상태는 검사하지 못했다.
한 개만 선택한 상태임에도
alert(document.cartFrm.cseq.length);
출력값은 3이 나온다.
장바구니에 존재하는 상품값 즉, checkbox 의 개수인 3이 출력되는 것이다.
앞서 자바스크립트에서 입력란의 name 이 하나인 경우는 단순 변수처럼 활용한다고 했다. 만약 checkbox 가 단 하나만 체크되었다면, 생성된 checkbox name은 배열이 아닌 변수로 남는 것이다. 단순히 document.(form의 name).(checkbox의 name).checked 로 checkbox 이름으로 값을 불러올 수 있다.
그래서 checkbox 가 1개 선택되어 변수처럼 활용할 수 있을 경우와, checkbox 가 두개 이상 선택되어 배열로 남은 경우를 구분하면 불필요하게 배열을 검사하는 수고를 덜할 수 있을 것이라 생각했는데.. 결과는 논리적 오류였던 것이다.
undefined 값이 나오려면, cseq 라는 name 의 checkbox 가 없어야 한다.
아무래도 자바스크립트에서는 length 를 문자열의 길이나 배열의 크기를 구할 때 모두 사용되어 혼동하기 쉬운 것 같다.
'Frontend > JavaScript' 카테고리의 다른 글
[JavaScript] Promise 문법과 async/await (0) | 2024.12.24 |
---|