본문으로 건너뛰기

폼 제출과 입력 값

자바스크립트 목차웹 페이지 움직이기레슨 70 / 76

목차

할 일 입력 칸에 글자를 치고 Enter를 누르거나 옆의 '추가' 단추를 누르면, 브라우저는 바깥 <form> 요소에 submit(제출) 이벤트를 일으킵니다. 이때 브라우저의 기본 새로고침을 **event.preventDefault()**로 막고, **input.value**에서 입력 글자를 꺼내 다듬는 법을 알아봅니다.

5단계 중 1단계. 입력 칸에 ' 빵 사기 '를 치고 제출하면 submit 리스너가 불리고 event.preventDefault()가 새로고침을 막습니다.

1폼 제출과 event.preventDefault()

할 일 앱의 폼(#todo-form) 안에는 입력 칸(#todo-input)과 제출 단추(<button type="submit">)⁠가 들어 있습니다.

<form id="todo-form">
  <input
    id="todo-input"
    type="text"
  />
  <button type="submit">
    추가
  </button>
</form>
결과 화면

단추에 'click' 리스너를 따로 붙이는 대신 form에 'submit' 리스너 하나만 붙이면, 단추를 마우스로 누를 때와 입력 칸에서 Enter 키를 칠 때를 한꺼번에 처리할 수 있습니다.

'use strict';

const form = document
  .querySelector('#todo-form');
const input = document
  .querySelector('#todo-input');

이어서 form에 'submit' 리스너를 등록합니다.

form.addEventListener(
  'submit',
  (event) => {
    event.preventDefault();
    const text =
      input.value.trim();
    if (text === '') return;
    console.log('추가:', text);
    input.value = '';
  },
);
실행 결과
'  장보기  '를 치고 Enter:
Console 탭: 추가: 장보기
(새로고침 없이 입력 칸 비워짐)
  1. event.preventDefault(): 브라우저에서 <form>의 기본 동작은 서버로 데이터를 보내며 페이지를 새로고침하는 것입니다. 첫 줄에서 event.preventDefault()⁠를 불러야 새로고침되어 변수들이 초기화되는 일을 막을 수 있습니다.
  2. input.value.trim(): 사용자가 입력 칸에 친 글자는 input.textContent가 아니라 **input.value**에 들어 있습니다. .trim()으로 앞뒤 공백을 깎아 내고, 공백만 쳐서 text === ''이면 return으로 빠져나옵니다.
  3. input.value = '': 할 일을 추가한 뒤에는 입력 칸에 빈 문자열을 대입해 칸을 깨끗이 비웁니다.

2input.value는 언제나 문자열이다

<input type="number">⁠처럼 숫자 입력 칸을 쓰더라도, 자바스크립트에서 읽은 **input.value의 타입은 언제나 string(문자열)**입니다.

두 입력 칸에 2와 3을 치고 Number()로 바꾸지 않은 채 +로 더하면 어떻게 되는지 Node로 확인해 봅니다.

const inA = { value: '2' };
const inB = { value: '3' };

console.log(typeof inA.value);
console.log(
  inA.value + inB.value,
);
console.log(
  Number(inA.value) +
    Number(inB.value),
);
실행 결과
string
23
5

'2' + '3'은 문자열 이어 붙이기가 되어 '23'이 나옵니다. 수량이나 금액처럼 숫자 계산을 해야 할 때는 반드시 **Number(input.value)**로 숫자로 바꾼 뒤에 계산합니다.

예제

결과를 먼저 생각한 뒤 펼쳐 보세요. 맞혀 보기는 점수에 들지 않습니다.

다음 cleanInput(raw) 함수는 입력 칸의 value 문자열을 받아 앞뒤 공백을 깎고, 빈 줄이면 null을, 글자가 있으면 그 글자를 돌려줍니다. 세 번 부른 출력은 무엇일까요?

function cleanInput(raw) {
  const text = raw.trim();
  if (text === '') return null;
  return text;
}

console.log(cleanInput('   '));
console.log(
  cleanInput('  우유 사기 '),
);
console.log(cleanInput('0'));
결과 보기
실행 결과
null
우유 사기
0
  • ' '는 .trim() 뒤에 ''가 되어 null을 돌려줍니다.
  • ' 우유 사기 '는 앞뒤 공백이 깎여 '우유 사기'가 되고, '0'은 빈 문자열이 아니므로 '0' 그대로 남습니다.

자주 틀리는 곳

  1. submit 리스너에서 event.preventDefault()⁠를 빼먹는다: 할 일을 추가하자마자 페이지가 깜빡이며 새로고침되고, 방금 추가한 할 일과 콘솔 출력이 순식간에 사라집니다.
  2. input.value를 숫자인 줄 알고 바로 +로 더한다: input.value는 늘 문자열이므로 '1000' + 500이 '1000500'이 됩니다. 숫자로 쓸 때는 Number(input.value)를 씁니다.
  3. 입력 칸의 글자를 input.textContent로 읽으려 한다: <input> 요소는 닫는 태그가 없는 빈 요소라 textContent가 언제나 ''입니다. 입력 칸의 글자는 읽을 때도 비울 때도 **input.value**를 씁니다.
  4. 공백만 친 입력을 거르지 않는다: input.value === ''만 검사하면 스페이스바만 여러 번 친 ' '가 통과해 빈 할 일 줄이 만들어집니다. 반드시 **input.value.trim() === ''**로 검사합니다.

확인 문제

  1. <form> 안의 제출 단추에 'click' 리스너를 다는 대신 <form>에 'submit' 리스너를 달고 첫 줄에 event.preventDefault()⁠를 적는 까닭 두 가지를 쓰세요.
정답

첫째, 마우스로 단추를 누를 때와 입력 칸에서 Enter를 누를 때를 한 리스너로 모두 받을 수 있습니다. 둘째, event.preventDefault()⁠가 폼 제출 시 페이지가 새로고침되어 상태가 초기화되는 기본 동작을 막아 줍니다.

  1. 사용자가 입력 칸(input)에 ' 산책하기 '를 쳤습니다. 앞뒤 공백을 뺀 글자를 text 상수에 담고, 이어서 입력 칸을 비우는 두 줄을 쓰세요.
정답

첫 줄은 text = input.value.trim()⁠이고, 둘째 줄은 input.value = ''입니다.

  1. value="4"인 숫자 입력 칸 요소 q에서 console.log(q.value + 1);⁠을 실행하면 무엇이 찍히며, 5가 찍히게 하려면 어떻게 고쳐야 하나요?
정답

q.value가 문자열 '4'이므로 '41'이 찍힙니다. 5가 찍히게 하려면 Number(q.value) + 1로 고칩니다.

끝까지 내려오면 저절로 표시됩니다. 이 기기에만 저장합니다.

자바스크립트 목차로