barcode

[HTML 요소] 체크박스

Coding/JavaScript

저번 시간(이라고 해봐야 한참 전)에 알아봤던 라디오 버튼 기억나시쥬? 동글뱅이 버튼. 오늘 알아볼 체크박스 역시 그거랑 비슷한데 약간 다르다. 대충 Python의 for문과 while문같은 느낌.

 

See the Pen Checkbox 1 by koreanraichu (@koreanraichu) on CodePen.

대충 이렇게 생긴건데, 라디오버튼과 비슷하게 선택지를 제공해주지만 라디오버튼과 달리 여러개를 선택할 수 있다. 그래서 여러개 중 하나를 선택할때는 라디오버튼(예: 성별/태어난 달/별자리)을, 여러개를 골라도 되는 선택지에는 체크박스(예: 취미/관심사)를 주로 쓴다. 

 

근데 라디오버튼에도 CSS를 줬으면, 체크박스에도 줄 수 있나요? 줄 수 있죠.

See the Pen Checkbox 2 by koreanraichu (@koreanraichu) on CodePen.

라디오버튼이 그렇듯이 appearance: none;을 먼저 줘서 기본 형태를 없애야 한다. 그리고 기본 형태 없애고 width랑 height를 다 지정해줘야 이쁜 체크박스가... 되는데... 아오 세로정렬 왜 이렇게 개판났니...ㅠㅠ

 

하아니 근데 체크는 어디가고 뭔 동그라미가 있어여!! 이건 아니예욧!! 사실 여기서 끝이 아니라 좀 고급진 이미지로 체크박스를 커스터마이징 할 수 있다. 아니, 정말로.

input[type="checkbox"] {
  appearance: none;
  width: 1.5rem;
  height: 1.5rem;
  border: 2px dotted #999999;
  border-radius: 50%;
  background-color: #ffffff;
  transition: background 300ms;
}

input[type="checkbox"]:checked {
  background-color: #000000;
  border: 2px dotted #000000;
  border-radius: 50%;
}

input[type="checkbox"]:checked::after {
  content: '\2714';
  color: #ffffff;
  font-size: 16pt;
  line-height: 1em;
}

이런 식으로 after 주고(checked와 after를 같이 줄 수 있다) 거기에 contents로 특수문자를 넣던가… 이모지 해봤는데 된다.

 

내가 된다고 했잖아요…

 

input[type="checkbox"] {
  appearance: none;
  width: 1.5rem;
  height: 1.5rem;
  border: 2px dotted #999999;
  border-radius: 50%;
  background-color: #ffffff;
  transition: background 300ms;
}

input[type="checkbox"]:checked {
  background-image: url('https://cdn.icon-icons.com/icons2/1744/PNG/512/3643781-check-checklist-complete-done-mark_113406.png');
  background-position: center;
  background-size: cover;
  border: none;
  border-radius: 50%;
}

만약 본인이 이미지도 같이 올릴거다 그러면 이런 식으로 배경이미지 지정해서 써도 된다. 이건 체크 전/체크 후 둘 다 가능.

 

그럼 오늘 배운 걸 응용해서 뭔가 만들어보자. 오늘 만들 건 파스타 재료 픽업용 페이지인데… 아니 이거 집에서 만드는거니까 오해는 하지 말고.

 

본인 블로그나 인별을 한번이라도 봤다면 알겠지만 본인 집에서 해먹는 파스타는 면이 착한 사람만 보이는 건더기가 급나 완전 핵쌉많은 파스타다. 그리고 건더기 종류는 보통 금요일에 결정해서 장 봐서 토요일에 해먹는 편... 물론 엄마 의견도 반영된 게 함정. 아무튼, 파스타에는 면 1종류(양심에디션/밀가루에디션)와 소스 1종류(그때그때 다름), 건더기 최대 5종까지를 넣는다. 그래서 뭐 만들길래 파스타 얘기냐고? 이거요.


위에서도 설명했듯 면 하나, 소스 하나에 건더기 급나 퍼붓는 구조이기 때문에 면과 소스는 하나씩만 고를 수 있다. 그리고 건더기는 뭐 본인 위장이 허락하는 한 뭐… 알아서 넣으시고…

 

input {
  margin: 5px 5px 15px 5px;
  vertical-align: middle;
}

input[type="radio"] {
  appearance: none;
  width: 1.5em;
  height: 1.5em;
  border: 1px solid #aaaaaa;
  border-radius: 50%;
  transition: 0.2s;
}

input[type="radio"]:checked {
  border: none;
}

input[type="radio"]:checked::after {
  content:'❤️';
}

input[type="checkbox"] {
  appearance: none;
  width: 1.5em;
  height: 1.5em;
  border: 1px solid #aaaaaa;
  border-radius: 50%;
  transition: 0.2s;
}

input[type="checkbox"]:checked {
  border: none;
}

input[type="checkbox"]:checked::after {
  content:'❤️';
}

사실 포크 이모지 했는데 배경이 흰색이라 그런가 안보이더라…

 

이걸 만들었으면 이제 자바스크립트를 통해 출력할건데... 그죠 이걸 가져와야 하는데... 어떻게?

const pastaNoodle = document.getElementsByName('noodle');
const pastaSaude = document.getElementsByName('sauce');
const pastaTopping = document.getElementsByName('topping');

console.log(pastaNoodle);

뭘 어떻게 갖고와요 이름으로 가져와야지… 그리고 선택됐는지를 확인하고 선택된 값에 해당하는 걸 출력해야 한다. 그죠?

 

readytocook.addEventListener('click',(e)=>{
  pastaNoodle.forEach((item) => {
    if (item.checked && item.value == "pasta") {
      noodle = "파스타";
    }
    else if (item.checked && item.value == "tofunoodle") {
      noodle = "두부면";
    }
    else if (item.checked && item.value == "tofunoodlew") {
      noodle = "넓은 두부면";
    }
  });
  pastaSauce.forEach((item) => {
    if (item.checked && item.value == "tomato") {
      sauce = "토마토";
    }
    else if (item.checked && item.value == "cream") {
      sauce = "크림";
    }
    else if (item.checked && item.value == "rose") {
      sauce = "로제";
    }
    else if (item.checked && item.value == "basil") {
      바질크림
    }
  });
  
});

일단 라디오버튼까지는 forEach로 했다. 하나만 고르는거기 때문에 아이템이 선택되었다면 그 값에 따라 하나만 가져오면 되니까… 근데 문제는 체크박스다. 체크박스는 한번에 여러 개 고를 수 있고 지금 디폴트값이 두 개거든…

 

readytocook.addEventListener('click',(e)=>{
  pastaNoodle.forEach((item) => {
    if (item.checked && item.value == "pasta") {
      noodle = "파스타";
    }
    else if (item.checked && item.value == "tofunoodle") {
      noodle = "두부면";
    }
    else if (item.checked && item.value == "tofunoodlew") {
      noodle = "넓은 두부면";
    }
  });
  pastaSauce.forEach((item) => {
    if (item.checked && item.value == "tomato") {
      sauce = "토마토";
    }
    else if (item.checked && item.value == "cream") {
      sauce = "크림";
    }
    else if (item.checked && item.value == "rose") {
      sauce = "로제";
    }
    else if (item.checked && item.value == "basil") {
      바질크림
    }
  });
  pastaTopping.forEach((item) => {
    if (item.checked) {
      topping.push(item.value)
    }
  });
  pastapick.innerText = `${noodle}에 ${sauce}소스 그리고 토핑은 ${topping} 입니다.`;
  pastaReady.appendChild(pastapick);
});

아, 그냥 가져오길래 친절하게 배열에 넣어줬다. 근데 텍스트로는 안되나...

 

사실 두부면은 양심적인 픽임. 아무튼 그렇다... 근데 value에 한글 써도 되는거였어??? 

 

See the Pen 렛츠 파스타 by koreanraichu (@koreanraichu) on CodePen.

아무튼 여기서 써봅시다. 참고로 목이버섯은 파스타에 털어넣으면 꼬들꼬들하니 맛있다. 양송이버섯은 이마트에서 파는 갈색양송이 쓰는 중…