HTML, JavaScript :: 하나의 form 태그 내의 여러 개의 input을 submit하기 (Feat. Implicit submission)

Hayoung·2021년 6월 3일
4

JavaScript

목록 보기
3/5
post-thumbnail

오늘 오전에 위와 같은 레이아웃을 가진 리뷰 기능을 만들고 있었다.
구현 조건으로는 Enter 키를 누르면 리뷰가 추가되게끔 하는 것이었다.

그래서 submit 버튼은 별도로 만들지 않고, .id-input, .comment-input으로부터 입력값을 받아서 Enter 키를 눌러 submit시킨 뒤 입력값을 DOM에 추가시켜줘야했다.

하지만...

문제의 코드💦

<!-- index.html -->
<form class="form">
  <input class="id-input" type="text" placeholder="ID를 입력해주세요." maxlength="12" />
  <input class="comment-input" type="text" placeholder="리뷰를 입력해주세요." maxlength="300" />
</form>
// review.js
const form = document.querySelector(".form");
const idInput = document.querySelector(".id-input");
const commentInput = document.querySelector(".comment-input");

const getInputValue = (event) => {
  event.preventDefault();
  let idValue = idInput.value;
  let commentValue = commentInput.value;
  console.log(`ID: ${idValue}`);
  console.log(`COMMENT: ${commentValue}`);
};

const init = () => {
  form.addEventListener("submit", getInputValue);
};

init();

이번에 구현하던 상황은 <form> 태그 내에 input이 1개가 아니라는 점. input이 2개였다.

이 점을 개의치 않던 나는, 여느 때와 같이 <form>태그에 submit이벤트를 걸어주고
"이정도 쯤이야😎"라며 방심을 하고 있었다😂🥲

하지만...

(↑ Enter 열심히 치는 중이었습니다.)
하지만 콘솔은 너무나도 조용했다...🥲

getInputValue 함수의 console.log 자체가 출력이 안되는 것을 보면 submit 이벤트 자체가 발화되지 않는 듯 했다.
그래서 이것저것 시도해본 결과, input 두 개중에 하나를 지워보니 이상하게 이벤트가 발동됐다.

input이 두 개일 때(복수일 때)는 submit 이벤트가 발화되지 않는 걸까???🤔


문제의 원인

Implicit submission을 block🚫 해버림🤭

  • “If the form has no submit button, then the implicit submission mechanism must do nothing if the form has more than one field that blocks implicit submission, and must submit the form element from the form element itself otherwise.”
  • 출처: HTML Standard - 4.10.21.2 Implicit submission

HTML에는 명시적으로 지정된 Implicit submission이라는 매커니즘이 있다.
간단히 말하자면 <form> 태그 내부의 field에 입력을 한 후, Enter 키를 누르면 암묵적으로 submit 이벤트가 발화된다는 것이다.

아하. 지금까지 input이 하나 였을 때 submit버튼을 별도로 만들지 않아도 Enter 키를 누르면 submit 이벤트가 발동됐던 건 다 이 녀석 덕분이었구나.

그러나 ⭐️<form> 태그 내부에 submit 버튼이 없는 경우⭐️에,

  • Implicit submission을 막는(block) 요소가 2개 이상 있을 때: Implicit submission이 동작하지 않는다.
  • Implicit submission을 막는(block) 요소가 1개 있을 때: Implicit submission이 동작된다.

고 한다.
저기서 "Implicit submission을 막는(block) 요소"란 무엇일까?🤔

  • “For the purpose of the previous paragraph, an element is a field that blocks implicit submission of a form element if it is an input element whose form owner is that form element and whose type attribute is in one of the following states: Text, Search, URL, Telephone, E-mail, Password, Date, Month, Week, Time, Local Date and Time, Number”
  • 출처: HTML Standard - 4.10.21.2 Implicit submission

Implicit submission을 막는(block) 항목은 <form>의 내부에 있는 input 요소로, type 속성이 Text, Search, URL, Telephone, E-mail, Password, Date, Month, Week, Time, Local Date and Time, Number인 것들이 있다.

아하. Implicit submission을 막는(block) 항목에 <input type="text">가 있었다.
문제의 코드를 잘 보면,

<!-- index.html -->
<form class="form">
  <input class="id-input" type="text" placeholder="ID를 입력해주세요." maxlength="12" />
  <input class="comment-input" type="text" placeholder="리뷰를 입력해주세요." maxlength="300" />
</form>

Implicit submission을 막는(block) <input type="text">가 2개였다💦
그래서 Implicit submission이 동작되지 않았기 때문에 submit 이벤트가 발화되지 않았던 것이다.


해결 방법

그렇다면 Implicit submission을 막는(block) 요소가 2개 이상인 경우에도 Implicit submission이 동작하게 하기 위해서는 어떻게 해야할까?

힌트는 이미 위에서 언급되었다.

(...중략)
그러나 ⭐️<form> 태그 내부에 submit 버튼이 없는 경우⭐️에,

  • Implicit submission을 막는(block) 요소가 2개 이상 있을 때: Implicit submission이 동작하지 않는다.
  • Implicit submission을 막는(block) 요소가 1개 있을 때: Implicit submission이 동작된다.

"<form> 태그 내부에 submit 버튼이 없는 경우"에 <input type="text">이 2개 이상 존재해서는 안되는 거라면...

<form> 태그 내부에 submit 버튼을 만들어 주면 됨😁

<!-- index.html -->
<form class="form">
  <input class="id-input" type="text" placeholder="ID를 입력해주세요." maxlength="12" />
  <input class="comment-input" type="text" placeholder="리뷰를 입력해주세요." maxlength="300" />
  <input type="submit" /> <!-- 이 줄만 추가 -->
</form>

↓ JS는 변동사항 없음.

// review.js
const form = document.querySelector(".form");
const idInput = document.querySelector(".id-input");
const commentInput = document.querySelector(".comment-input");

const getInputValue = (event) => {
  event.preventDefault();
  let idValue = idInput.value;
  let commentValue = commentInput.value;
  console.log(`ID: ${idValue}`);
  console.log(`COMMENT: ${commentValue}`);
};

const init = () => {
  form.addEventListener("submit", getInputValue);
};

init();

문제없이 submit 이벤트가 잘 발동되는 모습💖
(submit 버튼은 클릭하지 않았고 Enter 키로 submit했습니다.)

하지만 Implicit submission을 막는 요소가 2개 이상 존재하여 submit 버튼을 설치할 수 밖에 없는 상황에서
submit 버튼이 영 거슬리고 숨기고 싶다면?

CSS로 간단하게 감춰주면 된다.

input[type="submit"] {
  display: none;
}

깔끔💖


Demo 🔍


마치며

예상치도 못한 곳에서 막혔기 때문에 당황했지만 HTML의 법칙(?)을 알게 되어 알찬 시간이었다.
그리고 방심하지 말 것...🙇‍♀️

아래의 참고자료가 정말 다했다.
지식을 공유해주시는 전세계의 개발자님들 모두 존경합니다💖

부족한 점, 틀린 부분은 마구마구 지적해주시면 감사하겠습니다.


참고자료

Form with two inputs not submitting? - Stack Overflow
HTML Standard - 4.10.21.2 Implicit submission

profile
Frontend Developer. 블로그 이사했어요 🚚 → https://iamhayoung.dev

3개의 댓글

comment-user-thumbnail
2021년 6월 19일

이제서야 이 글이 모두 이해가 되네요 크크 리액트로 댓글 기능 구현하기는 저에게 정말.. 많은 깨달음을 줬습니다,, 🥶

1개의 답글
comment-user-thumbnail
2023년 4월 19일

감사합니다 많은 도움이 되었습니다

답글 달기