✍️ What I Learned

[TIL] FormData, data-*

Jiwon() 2024. 1. 15. 23:51

 

πŸ’‘ μ‚¬μš©ν•œ ν°νŠΈλŠ” λ‘₯κ·Όλͺ¨κΌ΄μ΄λ©°, 전체적인 λ””μžμΈ 컨셉은 λ””μžμ΄λ„ˆ κΈΈν˜•μ§„λ‹˜ λΈ”λ‘œκ·Έμ˜ λ‘₯κ·Όλͺ¨κΌ΄ μ†Œκ°œ κ²Œμ‹œκΈ€μ—μ„œ λ”°μ™”λ‹€. ν•΄λ‹Ή κ²Œμ‹œκΈ€μ€ λ‘₯κ·Όλͺ¨κΌ΄ 폰트λ₯Ό Fixedsys ν°νŠΈμ™€ κ²°ν•©ν•˜κ³  λ‹€λ“¬μ–΄μ„œ 퍼블릭 도메인 λΌμ΄μ„ΌμŠ€λ‘œ λ°°ν¬ν•œ νŽ˜μ΄μ§€μ΄λ‹€.

 


FormData

  • FormData λŠ” λΈŒλΌμš°μ €μ— λ‚΄μž₯된 API둜 HTML 폼 데이터λ₯Ό μ‰½κ²Œ μ²˜λ¦¬ν•˜κ³  전솑할 수 μžˆλŠ” 객체이닀.
  • new ν‚€μ›Œλ“œλŠ” μžλ°”μŠ€ν¬λ¦½νŠΈ 객체의 μƒˆλ‘œμš΄ μΈμŠ€ν„΄μŠ€λ₯Ό 생성할 λ•Œ μ‚¬μš©λœλ‹€. μƒμ„±μž ν•¨μˆ˜λ₯Ό ν˜ΈμΆœν•  λ•Œ new ν‚€μ›Œλ“œλ₯Ό μ‚¬μš©ν•˜λ©΄ ν•΄λ‹Ή ν•¨μˆ˜κ°€ μƒμ„±μžλ‘œ λ™μž‘ν•˜λ©° μƒˆλ‘œμš΄ 빈 객체가 λ°˜ν™˜λœλ‹€. μ΄λ ‡κ²Œ μƒμ„±ν•œ FormData 객체의 λ‹€μ–‘ν•œ λ©”μ„œλ“œλ₯Ό ν™œμš©ν•˜μ—¬ 폼 데이터에 λŒ€ν•œ μž‘μ—…λ“€μ„ μ²˜λ¦¬ν•  수 μžˆλ‹€.
    • ex. 폼 데이터 μˆ˜μ§‘, 파일 μ—…λ‘œλ“œ, AJAX μš”μ²­ μ‹œ 데이터 전솑 λ“±
<form>
  <div class="form-control">
    <label for="playername">ν”Œλ ˆμ΄μ–΄ 이름</label>
    <input type="text" name="playername" id="playername" autocomplete="off" />
  </div>
  <div>
    <button type="button" class="btn btn-alt" id="cancel-config-btn">μ·¨μ†Œ</button>
    <button type="submit" class="btn">확인</button>
  </div>
</form>
const formElement = document.querySelector('form');
formElement.addEventListener('submit', savePlayerConfig);

// form을 submitν•  λ•Œμ˜ μ½œλ°±ν•¨μˆ˜
function savePlayerConfig(e) {
  e.preventDefault();
  const formData = new FormData(e.target);
  const enteredPlayername = formData.get('playername').trim();
  console.log(enteredPlayername);
}
  • λ°œμƒν•œ 이벀트 객체에 λ“€μ–΄μžˆλŠ” target 속성을 FormData에 κ°’μœΌλ‘œ 전달할 수 μžˆλ‹€.
    • 폼을 μ „λ‹¬ν•˜λ©΄ μžλ°”μŠ€ν¬λ¦½νŠΈκ°€ 이 폼을 λΆ„μ„ν•΄μ„œ name 속성이 폼 λ‚΄μ˜ μš”μ†Œλ₯Ό νƒμƒ‰ν•œλ‹€. name μ†μ„±μ˜ 속성값을 μ‚¬μš©ν•˜μ—¬ FormData의 데이터λ₯Ό 식별할 수 μžˆλ‹€.

 

id 속성과 name 속성

id 속성

  • HTML λ¬Έμ„œ λ‚΄μ—μ„œ 각 μš”μ†Œλ“€μ— λŒ€ν•œ κ³ μœ ν•œ μ‹λ³„μžμ΄λ‹€. λ™μΌν•œ λ¬Έμ„œ λ‚΄μ—μ„œ idλŠ” 쀑볡될 수 μ—†λ‹€.
  • 주둜 css μŠ€νƒ€μΌλ§μ΄λ‚˜ μžλ°”μŠ€ν¬λ¦½νŠΈμ˜ νŠΉμ • μš”μ†Œλ₯Ό μ„ νƒν•˜κ³  μ‘°μž‘ν•  λ•Œ μ‚¬μš©λœλ‹€.
<div id="uniqueId">This is a unique element.</div>

 

name 속성

  • 특히 폼 μš”μ†Œμ—μ„œ μ„œλ²„λ‘œ 데이터λ₯Ό 전솑할 λ•Œ μ‚¬μš©λ˜λ©°, μ„œλ²„μ—μ„œλŠ” 이 name 속성값을 톡해 ν•΄λ‹Ή 데이터λ₯Ό μ‹λ³„ν•œλ‹€.
  • 폼 μ•ˆμ—μ„œλŠ” 쀑볡될 수 μžˆλ‹€. ν•˜λ‚˜μ˜ 폼 μ•ˆμ—μ„œ μ—¬λŸ¬ μš”μ†Œκ°€ λ™μΌν•œ name을 κ°–κ³  μžˆμ„ 수 μžˆλ‹€.
  • 폼 데이터λ₯Ό μ„œλ²„μ— 전솑할 λ•Œ, 특히 λΌλ””μ˜€ λ²„νŠΌμ΄λ‚˜ μ²΄ν¬λ°•μŠ€ λ“± 그룹으둜 묢인 μš”μ†Œμ—μ„œ μ‚¬μš©λœλ‹€.
<input type="text" name="username">
<input type="radio" name="gender" value="male"> Male
<input type="radio" name="gender" value="female"> Female

 

 

 


submit 데이터 μ €μž₯ 및 반영: data-*

  • data-* μ „μ—­ νŠΉμ„±μ€ μ‚¬μš©μž 지정 데이터 νŠΉμ„±(custom data attributes)μ΄λΌλŠ” νŠΉμ„± 클래슀λ₯Ό ν˜•μ„±ν•¨μœΌλ‘œμ¨ μž„μ˜μ˜ 데이터λ₯Ό 슀크립트둜 HTMLκ³Ό DOM μ‚¬μ΄μ—μ„œ κ΅ν™˜ν•  수 μžˆλŠ” 방법이닀.
  • data-* 둜 μ„€μ •ν•΄ μ€€ λ°μ΄ν„°λŠ” dataset μ†μ„±μœΌλ‘œ μ‚¬μš©ν•  수 μžˆλ‹€.
<button id="edit-player-1-btn" data-playerid="1">
  ν”Œλ ˆμ΄μ–΄ 1의 μˆ˜μ •λ²„νŠΌ
</button>
<button id="edit-player-2-btn" data-playerid="2">
  ν”Œλ ˆμ΄μ–΄ 2의 μˆ˜μ •λ²„νŠΌ
</button>
// ν”Œλ ˆμ΄μ–΄ 1의 μˆ˜μ •λ²„νŠΌ
const editPlayer1BtnElement = document.getElementById('edit-player-1-btn');
// ν”Œλ ˆμ΄μ–΄ 2의 μˆ˜μ •λ²„νŠΌ
const editPlayer2BtnElement = document.getElementById('edit-player-2-btn');

editPlayer1BtnElement.addEventListener('click', openPlayerConfig);
editPlayer2BtnElement.addEventListener('click', openPlayerConfig);

let editedPlayer = 0;

const players = [
  {
    name: '',
    symbol: 'X',
  },
  {
    name: '',
    symbol: 'O',
  },
];

function openPlayerConfig(e) {
  editedPlayer = e.target.dataset.playerid; // dataset μ‚¬μš©
  playerConfigOverlayElement.style.display = 'block';
  backdropElement.style.display = 'block';
};

function savePlayerConfig(e) {
  e.preventDefault();
  const formData = new FormData(e.target);
  const enteredPlayername = formData.get('playername').trim(); // '     ' => ''

  if (!enteredPlayername) { // enteredPlayername === ''
    e.target.firstElementChild.classList.add('error');
    errorsOutputElement.textContent = '이름을 μž…λ ₯ν•΄μ£Όμ„Έμš”!';
    return; // return λ°˜ν™˜ μ‹œ μ•„λž˜μ˜ μ½”λ“œκ°€ μ‹€ν–‰λ˜μ§€ μ•Šκ³  μ—¬κΈ°μ„œ ν•¨μˆ˜μ˜ 싀행이 쀑단됨
  }

  const updatedPlayerDataElement = document.getElementById(`player-${editedPlayer}-data`)
  updatedPlayerDataElement.children[1].textContent = enteredPlayername;

  players[editedPlayer - 1].name = enteredPlayername;

  closePlayerConfig();
}

  • html νŒŒμΌμ—μ„œ 각 λ²„νŠΌμ— data-playerid 값을 μ„€μ •ν•œ λ’€ μžλ°”μŠ€ν¬λ¦½νŠΈλ‘œ λ²„νŠΌμ— μ΄λ²€νŠΈλ¦¬μŠ€λ„ˆ μ½œλ°±ν•¨μˆ˜μ—μ„œ e.target.dataset으둜 playerid 값을 확인할 수 μžˆλ‹€.
  • e.target.dataset.playerid λ˜λŠ” e.target.dataset['playerid']둜 value만 κΊΌλ‚΄μ„œ μ‚¬μš©ν•  μˆ˜λ„ μžˆλ‹€.