submit() 메소드와 submit 이벤트

yoondgu·2022년 6월 22일
0

오류 기록

목록 보기
1/10
post-thumbnail

JSP 도서쇼핑몰 구현하기를 세미프로젝트 주제로 진행하고 있다.
장바구니, 배송지에서 DB와의 상호작용으로 값을 조회하고, 변경하고, 삭제하고, 저장하는 기능을 구현했다.
해당 CRUD 기능이 실행됨에 따라 화면에 출력되는 내용이 달라져야 하는 부분이 많았는데,
(첫 실습이므로 해당 상황에서 ajax보다는 응답 및 요청의 흐름이 더 단순한, jsp페이지에 form입력값을 전달하는 방식으로 프로그래밍했다.)

한 화면에서 이벤트에 따라 각기 다른 경로로 폼 제출을 해야 하기 때문에(저장, 삭제, 변경 버튼..)
input태그나 button태그 그 자체에서 지원되는 폼 제출 방식 대신에,
모두 click이벤트에 대한 함수로 등록하여 함수 내에서 form의 action값을 설정할 수 있게 한 뒤, form.submit()을 실행했다.

그런데 form태그의 onsubmit 이벤트에 걸어두었던 입력값의 유효성을 체크하는 내용(return checkInputValue();)이 실행되지 않는다는 걸 알게 됐다.
함수에 문제가 있나 확인해보고, 여러 부분에 콘솔 출력을 해보다보니 아예 submit 이벤트가 발생하지 않고 있다는 걸 알았다.

초반에 코드 작성했을 때는 이런 문제가 없었어서, 왜 이런 결과가 나왔는지 알 수 없었다.
그래서 구글링을 해보았다.

이유는 간단했다.
HTMLFormELement.submit() 메소드는 애초에 submit 이벤트를 발생시키지 않는 메소드이기 때문이었다.. ^^..

https://stackoverflow.com/questions/45663756/why-submit-method-didnt-trigger-onsubmit-event
https://developer.mozilla.org/en-US/docs/Web/API/HTMLFormElement/submit

그러니까 form.submit() 메소드는 폼입력값을 서버로 제출해주지만, submit 이벤트는 발생시키지 않으므로
onclick에 등록한 함수에서 form.submit()을 통해 폼을 제출한다면
폼은 정상적으로 제출되지만, submit이벤트는 발생하지 않기 때문에, onsubmit="" 부분에 등록해놓은 내용은 실행되지 않는다.

When you call the form's submit function, the submit event is not fired. This is by design, the assumption is that if you're triggering the submission from code, you've already done any necessary validation. (Note that this is true of the HTMLFormElement#submit function; it is not necessarily true of the wrappers libraries put around it.)
https://stackoverflow.com/questions/19847203/form-onsubmit-not-getting-called/19847255#19847255

StackOverflow에서는 이에 대한 해결책으로 주로 아래와 같은 내용을 제시하는 것 같다.
1. 꼭 필요한 게 아니라면, submit()메소드를 다른 이벤트에 등록하기보다는 일반적인 폼 제출(type=submit인 input, button태그) 방법을 권장
2. submit이벤트에 대한 default값을 prevent하고, 새 이벤트처럼 재정의하여 사용하기

하지만 나의 지금 상황 같은 경우는
1. 여러 action값을 설정하기 위해 submit()메소드가 꼭 필요하고,
2. 다른 페이지에서는 기본 submit이벤트를 활용하기도 하므로 아직 잘 모르는 상태에서 혼선을 가져올 수 있겠다고 판단해서

click이벤트에 등록한 함수에 checkInputValue()와 같은 기능을 해주는 코드를 포함시켰다. 그래도 충분히 간단히 해결되는 문제이기 때문이다.
다만 왜 이런 문제가 생겼는지, 이 해결방법이 맞는지 혼란스러웠기 때문에 기록해둔다.
자바 위주로 공부를 한 상태여서 그런지 첫 프로젝트를 진행중인 지금 생각보다 자바스크립트와 사투를 벌이는 시간이 훨씬 많다.

	/*
		전달값 중 하나라도 누락되면 alert창을 띄우고 false를 반환한다.
	*/
	function checkInputValue() {
		
		let addrField = document.getElementById("address");
		if (addrField.value === '주소지를 선택하세요' || addrField.value === '' || addrField.value === ' ') {
			alert('주소지를 입력하세요.')
			return false;
		}
		
		let postcodeField = document.getElementById("postcode");
		if (parseInt(postcodeField.value) == NaN) {
			alert('우편번호가 유효하지 않습니다.')
			return false;
		}
		
		return true;
	}
	
	
	/*
		저장 버튼을 누르면 실행되는 이벤트핸들러 함수.
		'기본 배송지로 저장' 체크박스에 체크되어있고, 현재 선택 배송지번호가 기본 배송지번호와 같다면 부모창으로 폼을 제출하고, 현재 창을 닫는다.
		'기본 배송지로 저장' 체크박스에 체크되어있지 않다면 현재 창으로 폼을 제출한다. (새로 저장하는 것이므로 저장 배송지 번호 = 기본 배송지 번호 일 경우는 없다.)
	*/
	function addAddress() {
		
		if (!checkInputValue()) {
			return;
		}
		
		let form = document.getElementById("address-form");
		let selectedAddressNo = document.getElementById("hidden-selectedAddressNo").value;
		let defAddressNo = document.getElementById("hidden-defAddressNo").value;
		
		let isCheckedStatus = document.querySelector("input[name=isChecked]").checked;
		let wasDefAddressSelected = selectedAddressNo === defAddressNo;
		
		if (isCheckedStatus && wasDefAddressSelected) {
			// 부모창(list.jsp페이지를 보고있던 브라우저)으로 폼을 제출한다.
			window.opener.name = 'parentName'
			form.setAttribute("target", 'parentName');
			form.setAttribute("action", 'addAddress.jsp');

			form.submit();
			window.close();
		} else {
			form.setAttribute("action", 'addAddress.jsp');
			form.submit();
		}
	}

0개의 댓글