본문으로 건너뛰기

폼 구성과 검증

분류: 폼 구성과 검증

필드셋 · 선택 그룹 · 유효성 검사 상태를 한 화면에 조합한 실제 업무 상담 폼 예제입니다. 왼쪽(col-lg-7)에는 fieldset.form-fieldset으로 고객 정보 입력 필드를 묶고, 필드마다 is-valid/is-invalid를 붙여 검증 결과를 valid-feedback/invalid-feedback 문구로 보여줍니다. 오른쪽(col-lg-5)에는 상담 유형을 고르는 form-selectgroup, 관심 서비스를 고르는 필 스타일 선택 그룹, 그리고 스위치·체크박스 동의 항목을 배치했습니다.

.card (폼 구성과 검증)
└── .card-body
└── .row.row-cards
├── .col-lg-7
│ └── fieldset.form-fieldset (고객 상담 정보)
│ └── .row → 고객명(is-valid) · 연락처(is-invalid) · 피팅 희망일 · 담당자 · 요청사항
└── .col-lg-5
├── .form-selectgroup (상담 유형: 라디오)
├── .form-selectgroup.form-selectgroup-pills (관심 서비스: 체크박스)
└── .form-check.form-switch / .form-check (알림 발송 · 약관 동의)

소스

<div class="card overflow-auto mt-3" id="example-forms">
<div class="card-status-top bg-orange"></div>
<div class="card-header">
<div>
<h3 class="card-title">폼 구성과 검증</h3>
<div class="card-subtitle">Form elements · Fieldset · Selectgroup · Validation states</div>
</div>
</div>
<div class="card-body">
<div class="row row-cards">
<div class="col-lg-7">
<fieldset class="form-fieldset">
<legend class="h4">고객 상담 정보</legend>
<div class="row">
<div class="col-md-6 mb-3">
<label class="form-label required" for="sample-customer-name">고객명</label>
<input type="text" id="sample-customer-name" class="form-control is-valid" value="김하늘" autocomplete="off" required>
<div class="valid-feedback">고객 정보가 확인되었습니다.</div>
</div>
<div class="col-md-6 mb-3">
<label class="form-label required" for="sample-customer-phone">연락처</label>
<input type="tel" id="sample-customer-phone" class="form-control is-invalid" value="010-1234" autocomplete="off" required aria-describedby="sample-customer-phone-feedback">
<div id="sample-customer-phone-feedback" class="invalid-feedback">휴대전화 번호 전체를 입력해 주세요.</div>
</div>
<div class="col-md-6 mb-3">
<label class="form-label" for="sample-fitting-date">피팅 희망일</label>
<input type="date" id="sample-fitting-date" class="form-control" value="2026-08-25">
</div>
<div class="col-md-6 mb-3">
<label class="form-label" for="sample-consultant">담당자</label>
<select id="sample-consultant" class="form-select">
<option>담당자를 선택하세요</option>
<option selected>김민서 디자이너</option>
<option>이서준 디자이너</option>
</select>
</div>
<div class="col-12">
<label class="form-label" for="sample-customer-request">요청사항</label>
<textarea id="sample-customer-request" class="form-control" rows="3" placeholder="선호 스타일, 예산, 행사 일정 등을 입력하세요.">레이스 소매와 A라인 스타일을 선호합니다.</textarea>
</div>
</div>
</fieldset>
</div>
<div class="col-lg-5">
<div class="mb-4">
<label class="form-label">상담 유형</label>
<div class="form-selectgroup">
<label class="form-selectgroup-item">
<input type="radio" name="sample-consult-type" value="visit" class="form-selectgroup-input" checked>
<span class="form-selectgroup-label">
<i class="f:20 mr:4 ti ti-building-store"></i> 방문
</span>
</label>
<label class="form-selectgroup-item">
<input type="radio" name="sample-consult-type" value="phone" class="form-selectgroup-input">
<span class="form-selectgroup-label">
<i class="f:20 mr:4 ti ti-phone"></i> 전화
</span>
</label>
<label class="form-selectgroup-item">
<input type="radio" name="sample-consult-type" value="video" class="form-selectgroup-input">
<span class="form-selectgroup-label">
<i class="f:20 mr:4 ti ti-video"></i> 화상
</span>
</label>
</div>
</div>
<div class="mb-4">
<label class="form-label">관심 서비스</label>
<div class="form-selectgroup form-selectgroup-pills">
<label class="form-selectgroup-item">
<input type="checkbox" name="sample-service" value="custom" class="form-selectgroup-input" checked>
<span class="form-selectgroup-label">맞춤 제작</span>
</label>
<label class="form-selectgroup-item">
<input type="checkbox" name="sample-service" value="rental" class="form-selectgroup-input">
<span class="form-selectgroup-label">드레스 대여</span>
</label>
<label class="form-selectgroup-item">
<input type="checkbox" name="sample-service" value="accessory" class="form-selectgroup-input">
<span class="form-selectgroup-label">액세서리</span>
</label>
</div>
</div>
<label class="form-check form-switch">
<input class="form-check-input" type="checkbox" checked>
<span class="form-check-label">예약 하루 전 알림 발송</span>
</label>
<label class="form-check mt-3">
<input class="form-check-input" type="checkbox">
<span class="form-check-label required">개인정보 수집 및 이용에 동의합니다.</span>
</label>
</div>
</div>
</div>
</div>

사용된 주요 클래스

클래스역할
form-fieldset관련 필드들을 하나의 테두리 있는 영역으로 묶는 필드셋 스타일
h4(legend에 적용)필드셋 상단 제목(<legend>)을 4단계 제목 크기로 표시
form-control텍스트/전화/날짜/텍스트영역 입력의 기본 스타일
form-select담당자를 고르는 <select>의 기본 스타일
form-label각 입력 위 라벨 텍스트
required라벨(form-label)이나 텍스트(form-check-label)에 붙여 필수 항목 표시
is-valid / valid-feedback입력값이 유효할 때 초록 테두리와 함께 표시되는 확인 문구
is-invalid / invalid-feedback입력값이 유효하지 않을 때 빨간 테두리와 함께 표시되는 오류 문구
form-selectgroup, form-selectgroup-item, form-selectgroup-input, form-selectgroup-label라디오/체크박스를 클릭 가능한 버튼형 선택지로 바꾸는 선택 그룹 구조
form-selectgroup-pills선택 그룹을 사각형 대신 필(pill) 모양으로 표시
form-check, form-check-input, form-check-label스위치·체크박스와 라벨을 묶는 기본 구조
form-switch체크박스를 토글 스위치 모양으로 표시(알림 발송 항목)
row, row-cards카드 레이아웃과 좌우 2단 배치를 위한 Bootstrap 그리드 행
col-lg-7, col-lg-5, col-md-6, col-12화면 크기별 좌우 컬럼 너비 지정
f:20 / mr:4master-css 속성형 클래스, 아이콘 크기(20px) / 오른쪽 여백(4px)
mb-3, mb-4, mt-3요소 사이 위/아래쪽 여백
ti, ti-building-store, ti-phone, ti-videoTabler Icons 폰트 아이콘, 상담 유형(방문/전화/화상)을 나타냄

실전 예제 페이지

HandStack 웹 호스트(wwwroot 모듈)를 기동한 뒤 /sample/ui-library/폼-구성과-검증.html 경로에서 렌더링 결과를 확인할 수 있습니다.

참고 자료