[javascript]select 박스 option 선택에 따른 input 입력창 추가/삭제

hyejinJo·2023년 12월 6일
0

Javascript / jQuery

목록 보기
5/8
  • select 박스에서 품목의 종류 개수를 입력하면, 개수에 따라 input 칸이 추가되는 기능을 구현해보았다. (품목은 4개까지 입력 가능)
  • 개수를 변경시, 개수가 적어지면 적어진 개수만큼 뒤에서부터 input 삭제, 입력값이 같이 제출될 수 있으므로 그에 따른 value 값도 빈 값(‘’) 로 초기화해주었다
<form class="item-field">
  <label for="amount">개수 입력</label>
  <div class="inner-box">
    <div class="input-wrap2 wrap1">
      <select id="amount" name="amount" onchange="changeAmount(this)">
        <option value="1">1</option>
        <option value="2">2</option>
        <option value="3">3</option>
        <option value="4">4</option>
      </select>
      <span></span>
    </div>
    <div class="input-wrap2 wrap2">
      <fieldset class="line-break">
        <label for="item1">품목1</label>
        <em class="txt">품목명을 입력해 주세요. <br>(: 테니스 스커트)</em>
        <input id="item1" name="item1" type="text" placeholder="품목명을 입력해 주세요. (예: 갤럭시 S4)" />
      </fieldset>
      <fieldset class="hide">
        <label for="item2">품목2</label>
        <input id="item2" name="item2" type="text" placeholder="품목명을 입력해 주세요." />
      </fieldset>
      <fieldset class="hide">
        <label for="item3">품목3</label>
        <input id="item3" name="item3" type="text" placeholder="품목명을 입력해 주세요." />
      </fieldset>
      <fieldset class="hide">
        <label for="item4">품목4</label>
        <input id="item4" name="item4" type="text" placeholder="품목명을 입력해 주세요." />
      </fieldset>
    </div>
  </div>
</form>
  • 화면에서만 inputdisplay: none; 을 주어 안보이기만 된다 생각했던,, form 제출을 하면 이전에 입력했던 값이 그대로 파라미터로 보내지는 것을 보고 난 바보인가 싶었다😂
  • input 요소들을 배열로 만든뒤 뒤에서부터 역순으로 제거했는데 식이 조금 복잡해서 헤맸다. 지워지는 input 을 감싸고있는 부모 fieldset 요소도 같이 지워줘서 화면에서 안보이게끔 구현했다.
// select 박스 - 기기 등록 개수 -------------------------------

const itemInputs = Array.from(document.querySelectorAll('.input-wrap2.wrap2 input'))
let previousValue = 1; // 이전에 입력한 품목 개수 값

const changeAmount = (e) => {
  const currentValue = parseInt(e.value) // 현재 입력한 품목 개수 값
  if (previousValue === currentValue) {
    return;
  } else if (previousValue < currentValue) { // 개수가 커질 때
    for (let i = previousValue - 1; i < currentValue; i++) {
      itemInputs[i].parentNode.classList.remove(('hide'))
    }
  } else if (previousValue > currentValue) { // 개수가 적어질 때
    const removeLength = itemInputs.length - currentValue

    // input 제거 시 value 도 함께 제거
    // 역순으로 removeLength 개 만큼의 input 요소 value를 ''로 초기화
    for (let i = itemInputs.length - 1; i >= itemInputs.length - removeLength; i--) {
      itemInputs[i].value = '';
      itemInputs[i].parentNode.classList.add(('hide'))
    }
  }
  previousValue = currentValue; // 이전 값 갱신

  // (테스트용) 현재 input value 값 배열
  const valueArr = itemInputs.map((input) => input.value)
  console.log(valueArr)
}

+ placeholder 기능 수동 구현

  • 모바일로 변형될 때 input 에 placeholder 텍스트가 줄바꿈 되어야했는데, placehoder 내에서 br 처리를 할 수가 없어 em 으로 대신 처리를 해주었다. (textarea 는 줄바꿈 가능하다는것을 또 중간에 배우게 되었다)

function placeholderHandler() {
  if(isMobile()) { // 모바일일 때만 input 이 줄바꿈 되는 구조
    const lineBreakInputs = document.querySelectorAll('.line-break input')
    lineBreakInputs.forEach((input) => {
      input.addEventListener('input', function(e) {
        const emText = e.target.previousElementSibling // 이전의 형제요소
        const parent = e.target.parentNode
        if (e.target.value) {
          emText.classList.add('hide') // 입력이 되는 순간 진짜 placeholder 처럼 사라짐
          parent.classList.add('h-auto') // 줄바꿈에 따라 높이값도 달라짐
        } else {
          emText.classList.remove('hide')
          parent.classList.remove('h-auto')
        }
      })
    })
  }
}
window.addEventListener('resize', function() { // 모바일일 때만 줄바꿈되기 때문에 사이즈 변경 이벤트 때도 함수 실행
  placeholderHandler();
});
placeholderHandler();
profile
FE Developer 💡

0개의 댓글