유저와 상호작용할 수 있는 폼 태그에 대해 알아봅시다.
form은 모든 폼 요소를 감싸며, 그 폼들이 어떤 방향으로 흘러갈지를 정의하는 곳입니다.
fieldset 엘리먼트는 폼 요소들을 그룹화합니다. 그룹한 이유는 legend 태그에 적습니다.
label은 명시적으로 폼 태그의 용도를 나타내며, label의 for 속성과 폼 태그의 id 속성을 연결하여 서로를 결합시킵니다.
aria-label은 스크린리더기가 늘 읽는 속성입니다.
<form>
<fieldset>
<legend>Fruit juice size</legend>
<p>
<input type="radio" name="size" id="size_1" value="small">
<label for="size_1">Small</label>
</p>
<p>
<input type="radio" name="size" id="size_2" value="medium">
<label for="size_2">Medium</label>
</p>
<p>
<input type="radio" name="size" id="size_3" value="large">
<label for="size_3">Large</label>
</p>
</fieldset>
<div>
<label for="username">Name: <abbr title="required" aria-label="required">*</abbr></label>
<input id="username" type="text" name="username">
</div>
</form>
공통 속성들
autofocus - 한 파일에 하나만 지정. 자동으로 포커싱해줌.
readonly - 값을 수정할 수 없지만 다른 데이터와 함께 서버로 전송됩니다.
disabled - 값을 수정할 수 없고 데이터도 함께 보낼 수 없습니다.
size - 인풋의 크기
placeholder - 인풋 안에 나타나는 대체 텍스트
spellcheck - 맞춤법 검사
type - 인풋의 용도
<input type="text" value="by default this element is filled with this text">
<textarea>
by default this element is filled with this text
</textarea>
종류
hidden - 보이지 않지만 데이터는 전송됨.
password - 비밀번호
checkbox - 체크박스: 아무 것도 체크하지 않으면 name값도 보내지지 않음. 처음에 checked를 가지고 있으면 :default css selector로 선택가능
radio - 라디오버튼: 아무 것도 체크하지 않으면 name값도 보내지지 않음. 처음에 checked를 가지고 있으면 :default css selector로 선택가능
file - 파일전송
submit, reset, button 3가지 용도의 버튼이 있습니다.
<button type="submit">Send your message</button>
이 엘리먼트가 폼 요소는 아니지만 추천 값을 보여주기에는 좋은 것 같습니다.
<label for="ice-cream-choice">Choose a flavor:</label>
<input list="ice-cream-flavors" id="ice-cream-choice" name="ice-cream-choice" />
<datalist id="ice-cream-flavors">
<option value="Chocolate">
<option value="Coconut">
<option value="Mint">
<option value="Strawberry">
<option value="Vanilla">
</datalist>
<select>
<option>1</option>
<option>2</option>
<option>3</option>
<option>4</option>
</select>
<textarea>
by default this element is filled with this text
</textarea>
form data에 함께 전송되진 않는다.
<form oninput="result.value=parseInt(a.value)+parseInt(b.value)">
<input type="range" id="b" name="b" value="50" /> +
<input type="number" id="a" name="a" value="10" /> =
<output name="result" for="a b">60</output>
</form>
<label for="file">File progress:</label>
<progress id="file" max="100" value="70"> 70% </progress>
<label for="fuel">Fuel level:</label>
<meter id="fuel"
min="0" max="100"
low="33" high="66" optimum="80"
value="50">
at 50/100
</meter>
form 태그는 모든 폼 요소를 감싸며, 그 폼들이 어떤 방향으로 흘러갈지를 정의하는 곳입니다.
<form action="/my-handling-form-page" method="post"></form>
http 통신
http 통신은 html 문서처럼 header와 body로 나누어져 있습니다.
header는 통신에 필요한 메타 데이터들을 담고 있고 body는 실제 보내는 데이터를 담고 있습니다.
대표적인 통신 방식으로 get은 url을 통해 자원을 요청하며, post는 데이터를 http body에 실어서 보냅니다.
데이터는 어떤 메소드로 보내느냐에 따라 보이는 형태는 다르지만 참조되어 만들어지는 내용은 같습니다.
name 속성이 데이터의 키가 되고, value속성이 데이터의 값이 됩니다.
name & value 쌍으로 데이터를 보내며 보통은 json형식을 취합니다.
<ul>
<li>
<label for="name">Name:</label>
<input type="text" id="name" name="user_name" />
</li>
<li>
<label for="mail">E-mail:</label>
<input type="email" id="mail" name="user_email" />
</li>
<li>
<label for="msg">Message:</label>
<textarea id="msg" name="user_message"></textarea>
</li>
파일 전송은 텍스트 데이터가 아니라 이진 데이터이므로 전송방식이 다른 폼 요소들과 다릅니다.
데이터의 형식이 무엇인지 말해주는 메타정보가 Content-Type 인데 다른 폼 요소들은 값이 application/xwww-form-urlencoded입니다.
이는 url 파라미터로 인코딩된 폼 데이터라는 뜻입니다.
파일 전송에는 content-type이 multipart/form-data로 되어야 합니다. 이는 form 의 enctype속성으로 정의해줄 수 있습니다.
<form method="post" action="https://www.foo.com" enctype="multipart/form-data">
<div>
<label for="file">Choose a file</label>
<input type="file" id="file" name="myFile">
</div>
<div>
<button>Send the file</button>
</div>
</form>
프론트 단에서 폼의 유효성을 검사하는 것은 폼 데이터가 올바른 형식으로 모두 갖춰져있는지를 확인하는 것입니다.
이런 검사를 해야하는 이유는 정보보안을 위해, 알맞은 양식을 보내야 오류가 없기 때문에 실시합니다.
유효성 검사를 백과 프론트 어디서 해야하는지에 대해 실무에서 논쟁이 많습니다.
둘 다 해야하지만 포인트가 다르죠. 백에서는 정말 맞는 값인지를 검사해야하고, 프론트는 위에서 언급한 부분을 검사해야 합니다.
특히, 보안을 다루는 부분은 클라이언트에서 다루면 안됩니다.
유효성 검사는 크게 폼요소에 내장된 검사와 자바스크립트로 만드는 검사가 있습니다.
여기서는 내장된 검사만 정리하겠습니다.
속성들
javascript를 사용하지 않는다면 css의 수도클래스를 이용하여 할 수 있습니다.
:valid
, :nvalid
(= :out-of-range
), :required
, :focus