하나만 선택하는 버튼과 다중 선택이 가능한 입력 폼 만들기


곰곰이 생각해보니 input의 radio와 checkbox 속성을 적용하여 그것을 버튼처럼 만드는 방법이 떠올랐다.

일단 전체 구조는 분리된 섹션 레이아웃이 하나의 폼이고 Submit 버튼 클릭 시 위에서 작성한 폼이 제출되는 형식이다.
기본 구조는
<form>
<section className='make_circle_name'>
<div className='make_circle_name_cont'>
<h3>① Make circle name</h3>
<label><textarea rows="1" placeholder='Enter 20 characters or less'></textarea></label>
</div>
</section>
... 나머지 섹션들
</form>
대충 이러한 구조이다.
그리고 새로 알게 된 label 태그에 대한 것
<input type="text" id="html" name=""/ >
<label for="html">
<label>
<input type="text" id="html" name=""/ >
</label>
보통 위에 있는 형식을 많이 볼 텐데 처음에 아래처럼 작성하다 이게 아닌가 싶어서 찾아보았다. 그 결과 둘 다 맞는 형식이었지만 전자의 경우 for 속성을 붙여주어야 하고 input의 id와 같은 값을 작성해야하고 후자의 경우는 이미 레이블 태그 안에 input이 포함되어있기 때문에 for 속성을 따로 작성하지 않는다는 점에서 차이가 있었다. 그리고 리액트에선 for 대신 htmlFor을 사용한다는 점 주의
<section className='make_circle_name'>
<div className='make_circle_name_cont'>
<h3>① Make circle name</h3>
<textarea id='name' rows="1" placeholder='Enter 20 characters or less'></textarea>
<label htmlFor='name'></label>
</div>
</section>
<section className='category_of_circle input_box'>
<div className='category_of_circle_cont'>
<h3>② Category of circle</h3>
<input type="radio" id="category" name="language" />
<label htmlFor=category>language</label>
</div>
</section>
그런데 생각해보니 카테고리와 캐릭터 영역은 같은 형태의 input 태그가 여러 번 나와서 저런 식으로 복붙해서 사용하는 방식은 코드 낭비이기도 하고 더욱 간결하게 표현할 수 있는 방법이 있을 것 같았다.
그래서 찾아본 결과 버튼 안에 있는 값을 배열 형태로 변수에 저장하여 불러오는 방식을 선택했다.
const categories = [
"language", "animation", "media", "photo", "exhibition",
"shopping", "sport", "game", "DIY", "casual",
"music", "book", "food", "baking"
];
// 카테고리 별 영역을 변수에 담아 저장
<section className='category_of_circle input_box'>
<div className='category_of_circle_cont'>
<h3>② Category of circle</h3>
{categories.map(category => ( // 배열 순회
<div key={category}>
<input type="radio" id={category} name="category" value={category} />
<label htmlFor={category}>{category}</label>
</div> // 배열 안에 있는 카테고리 클릭 시 각각의 데이터로 전달됨
))}
</div>
</section>
radio와 checkbox를 버튼처럼 만들어서 사용하기
.input_box label{
padding: 7px 17px;
box-sizing: border-box;
color: #000;
border: 1px solid #000;
border-radius: 50px;
display: inline-block;
margin: 10px;
cursor: pointer;
}
.input_box input{
display: none; // 안보이도록 설정
}
.input_box input:checked + label { // 인접 선택자 +를 사용하여 label 태그 선택
background: #000;
color: #fefefe;
}