본문 바로가기
Front-end

submit 버튼 쓰지 않고 submit하기

by softserve 2023. 1. 12.
반응형

1. 폼 태그에 대한 간략한 설명

 

<form> 태그는 사용자로부터 값을 입력받기 위해 사용됩니다.

최근 개발되는 웹 또는 앱 서비스의 경우 가입 시 개인 정보 수집을 최소화하려는 경향을 보이고 있긴 합니다만,

전통적인 회원가입 페이지를 한번 떠올려보죠.

사용자는 <form>의 내부에 있는 <input>에 아이디와 비밀번호를 입력하고,

<select>에서 생년월일을 고르고, 라디오 버튼이나 체크박스까지 모두 선택한 뒤에

마지막으로 <button> 또는 <input type="submit"> 을 누릅니다.

이 '제출하기' 라는 행위를 통해서 폼에 입력된 데이터들은 서버로 전송되게 됩니다.

 

2. Submit 버튼의 대안

 

1) submit() 메서드로 submit하기

button이 아닌 어떤 html 요소를 클릭했을 때 submit이 이루어지도록 하려면,

onclick 이벤트 발생 시 특정 폼을 지정하여 submit 하는 스크립트를 넣어주면 됩니다.

<a href="javascript:void(0);" onclick="document.forms['formname'].submit();">

 

2) 이런 짓을 하는 이유

멀쩡한 submit 버튼을 놔두고 왜 굳이 이렇게 하느냐?

모종의 이유로 submit 버튼이 폼 내부에 위치할 수 없는 경우,

디자인을 의뢰했더니 업체에서 button 이 아닌 <a> 를 화려하게 꾸며서 보내준 경우 등등

평범한 방법으로 submit을 할 수 없을 때 이 submit() 을 유용하게 사용할 수 있습니다.

물론 전자의 경우 HTML 만으로도 해결이 가능하고 ( 4. 에서 소개) 후자의 경우 CSS를 조금 손보면 될 일이긴 하지만,

상황에 맞게 적절히 활용할 수 있는 다양한 방안들을 가지고 있으면 더 좋겠죠?

 

3) 문제점

submit() 메서드는 button과 같이 submit을 수행하지만,

① form의 onsubmit event handler를 실행시키지 않으며,

② Constraint validation이 트리거되지 않습니다.

https://developer.mozilla.org/en-US/docs/Web/API/HTMLFormElement/submit

onsubmit 이란 submit이 이루어지기 전에 유효성 검사를 수행하기 위해 사용할 수 있는 이벤트입니다.

<form name="myform" method="post" action="" onsubmit="return validategogo()">
	...
</form>

submit 버튼을 클릭하더라도 데이터를 전송하기 전에 validategogo() 에 따라서 유효성 검사를 수행한 뒤, 그 결과가 false라면 submit을 중단할 수 있습니다.

예를 들어, 아이디에 형식 제한을 걸고 싶다 하면

function validategogo() {
    const id = document.forms["myform"]["id"].value;
    const pattern = /^[a-zA-Z0-9]{4,10}$/;
    if(!pattern.test(id) {
        alert("아이디는 4~10자리 영문, 숫자만 가능합니다!!!");
        return false;
    }
}

이렇게 해주면 됩니다. id가 pattern 정규식에 맞지 않으면 alert() 한 뒤에 false를 리턴해주므로 submit은 일어나지 않습니다.

그런데 submit()을 사용할 경우 이 onsubmit 이벤트 핸들러가 실행되지 않는다는 거죠. 사용자가 아이디를 @@@ 라고 하든 !!!! 라고 하든 막을 수가 없다는 겁니다.

constraint validation 이란 html 자체에서 제공하는 유효성 검사를 말합니다. html5에서 도입된 input type="URL", "email" 등 input 태그의 타입을 통해서 또는 pattern, min, max 등의 attribute를 통해서 제약을 걸 수도 있습니다.

하지만 이것 역시 submit()을 했을 경우에는 적용되지 않기에, 아이디에 required를 걸어봤자 아이디가 공백인 상태로 회원가입을 하는 것을 막을 수 없게 됩니다.

https://developer.mozilla.org/en-US/docs/Web/HTML/Constraint_validation

 

3. 대안의 대안

 

1) requestSubmit() 메서드

requestSubmit() 은 submit()과 달리 submit 이벤트를 일으키며, 유효성 검사가 가능합니다. 이에 더해서 event.preventDefault를 통해서 취소될 수도 있습니다.

https://developer.mozilla.org/en-US/docs/Web/API/HTMLFormElement/requestSubmit

function func() {
    let myform = document.querySelector("form");
    if(myform.requestSubmit) {
        myform.requestSubmit();
    } else {
        myform.submit();
    }
}

 

위 함수는 requestSubmit이 가능하면 requestSubmit()을 실행하고

그렇지 않을 경우 submit()을 실행합니다.

 

2) click() 메서드를 이용한 꼼수

또는 submit 버튼을 숨겨놓고 onclick 이벤트로 submit 버튼을 클릭하게 할 수 있습니다.

<input type="submit" id="hiddenSubmit" style="display:none;">
<a href="javascript:document.querySelector('#hiddenSubmit').click();"></a>

 

4. 다시 기본으로

 

지금까지 submit 버튼이 아닌 요소를 submit 버튼처럼 사용하거나 form의 외부에서 submit을 하기 위해 스크립트를 이용하는 방법들을 살펴보았습니다만, 사실 스크립트를 사용하지 않고도 이 문제는 해결이 가능합니다.

1) form 속성으로 외부에서 서브밋하기

<form id="myform">
	...
</form>
<input type="submit" form="myform">

 

submit 버튼의 form 속성에 form의 아이디를 넣어주면

form 외부에서도 해당 폼에 대한 submit을 수행할 수 있습니다.

IE에서는 안 된다고 하지만... 아직도 IE를 사용하는 사람이 있다구요??!

 

2) label

https://stackoverflow.com/questions/7020659/submit-form-using-a-button-outside-the-form-tag

에서 발견한 건데,

<form>
	<input type="submit" id="submitButton">
</form>
<label for="submitButton" style="cursor:pointer;">버튼</label>

이렇게 form 내부의 submitButton 에 대한 라벨을 form 외부에 두면 라벨 영역을 클릭하여 submit이 가능합니다!

반응형

댓글