以下は、Bootstrapのフォームコントロールで完全に構築されたサンプルフォーム。必要な各フォームグループには、フォームを完了せずに送信しようとすると切り替わる検証状態がついている。
.container {
max-width: 960px;
}
.lh-condensed { line-height: 1.25; }
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>精算フォーム</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.6.2/dist/css/bootstrap.min.css" integrity="sha384-xOolHFLEh07PJGoPkLv1IbcEPTNtaed2xpHsD9ESMhqIYd0nLMwNLD69Npy4HI+N" crossorigin="anonymous">
//cssファイルの設定など
</head>
<body class="bg-light">
<div class="container">
<div class="py-5 text-center">
<img class="d-block mx-auto mb-4" src="../images/bootstrap-solid.svg" alt="" width="72" height="72">
<h2>精算フォーム</h2>
<p class="lead">以下は、Bootstrapのフォームコントロールで完全に構築されたサンプルフォーム。必要な各フォームグループには、フォームを完了せずに送信しようとすると切り替わる検証状態がついている。</p>
</div>
<div class="row">
<div class="col-md-4 order-md-2 mb-4">
<h4 class="d-flex justify-content-between align-items-center mb-3">
<span class="text-muted">カート</span>
<span class="badge badge-secondary badge-pill">3</span>
</h4>
<ul class="list-group mb-3">
<li class="list-group-item d-flex justify-content-between lh-condensed">
<div>
<h6 class="my-0">商品名</h6>
<small class="text-muted">簡単な説明</small>
</div>
<span class="text-muted">¥12000</span>
</li>
<li class="list-group-item d-flex justify-content-between lh-condensed">
<div>
<h6 class="my-0">2番目の商品</h6>
<small class="text-muted">簡単な説明</small>
</div>
<span class="text-muted">¥8000</span>
</li>
<li class="list-group-item d-flex justify-content-between lh-condensed">
<div>
<h6 class="my-0">3番目の商品</h6>
<small class="text-muted">簡単な説明</small>
</div>
<span class="text-muted">¥5000</span>
</li>
<li class="list-group-item d-flex justify-content-between bg-light">
<div class="text-success">
<h6 class="my-0">プロモーションコード</h6>
<small>EXAMPLECODE</small>
</div>
<span class="text-success">-¥5000</span>
</li>
<li class="list-group-item d-flex justify-content-between">
<span>合計 (円)</span>
<strong>¥20000</strong>
</li>
</ul>
<form class="card p-2">
<div class="input-group">
<input type="text" class="form-control" placeholder="プロモーションコード">
<div class="input-group-append">
<button type="submit" class="btn btn-secondary">適用</button>
</div>
</div>
</form>
</div>
<div class="col-md-8 order-md-1">
<h4 class="mb-3">請求先住所</h4>
<form class="needs-validation" novalidate>
<div class="row">
<div class="col-md-6 mb-3">
<label for="familyName">姓</label>
<input type="text" class="form-control" id="familyName" placeholder="" value="" required>
<div class="invalid-feedback">
名字を入力してください
</div>
</div>
<div class="col-md-6 mb-3">
<label for="givenName">名</label>
<input type="text" class="form-control" id="givenName" placeholder="" value="" required>
<div class="invalid-feedback">
名前を入力してください
</div>
</div>
</div>
<div class="mb-3">
<label for="username">ユーザー名</label>
<div class="input-group has-validation">
<div class="input-group-prepend">
<span class="input-group-text">@</span>
</div>
<input type="text" class="form-control" id="username" placeholder="ユーザー名" required>
<div class="invalid-feedback" style="width: 100%;">
ユーザー名が必要です
</div>
</div>
</div>
<div class="mb-3">
<label for="email">Eメール <span class="text-muted">(任意)</span></label>
<input type="email" class="form-control" id="email" placeholder="you@example.com">
<div class="invalid-feedback">
配送の更新に有効なメールアドレスを入力してください
</div>
</div>
<div class="mb-3">
<label for="address">住所</label>
<input type="text" class="form-control" id="address" placeholder="地番" required>
<div class="invalid-feedback">
配送先住所を入力してください
</div>
</div>
<div class="mb-3">
<label for="address2">住所 2 <span class="text-muted">(任意)</span></label>
<input type="text" class="form-control" id="address2" placeholder="アパート・マンション名">
</div>
<div class="row">
<div class="col-md-5 mb-3">
<label for="pref">都道府県</label>
<select class="custom-select d-block w-100" id="pref" required>
<option>選択...</option>
<option>北海道</option>
</select>
<div class="invalid-feedback">
都道府県を選択してください
</div>
</div>
<div class="col-md-4 mb-3">
<label for="city">市町村</label>
<select class="custom-select d-block w-100" id="city" required>
<option>選択...</option>
<option>札幌市</option>
</select>
<div class="invalid-feedback">
市町村を選択してください
</div>
</div>
<div class="col-md-3 mb-3">
<label for="zip">郵便番号</label>
<input type="text" class="form-control" id="zip" placeholder="" required>
<div class="invalid-feedback">
郵便番号を入力してください
</div>
</div>
</div>
<hr class="mb-4">
<div class="custom-control custom-checkbox">
<input type="checkbox" class="custom-control-input" id="addressCheck">
<label class="custom-control-label" for="addressCheck">配送先住所は、請求先住所と同じです</label>
</div>
<div class="custom-control custom-checkbox">
<input type="checkbox" class="custom-control-input" id="keepCheck">
<label class="custom-control-label" for="keepCheck">次回のために、この情報を保存する</label>
</div>
<hr class="mb-4">
<h4 class="mb-3">お支払い方法</h4>
<div class="d-block my-3">
<div class="custom-control custom-radio">
<input id="credit" name="paymentMethod" type="radio" class="custom-control-input" checked required>
<label class="custom-control-label" for="credit">クレジットカード</label>
</div>
<div class="custom-control custom-radio">
<input id="debit" name="paymentMethod" type="radio" class="custom-control-input" required>
<label class="custom-control-label" for="debit">デビットカード</label>
</div>
<div class="custom-control custom-radio">
<input id="paypal" name="paymentMethod" type="radio" class="custom-control-input" required>
<label class="custom-control-label" for="paypal">PayPal</label>
</div>
</div>
<div class="row">
<div class="col-md-6 mb-3">
<label for="cc-name">カードの名義</label>
<input type="text" class="form-control" id="cc-name" placeholder="" required>
<small class="text-muted">カード上に表示されているフルネーム</small>
<div class="invalid-feedback">
カードの名義を入力してください
</div>
</div>
<div class="col-md-6 mb-3">
<label for="cc-number">クレジットカード番号</label>
<input type="text" class="form-control" id="cc-number" placeholder="" required>
<div class="invalid-feedback">
クレジットカード番号を入力してください
</div>
</div>
</div>
<div class="row">
<div class="col-md-3 mb-3">
<label for="cc-expiration">有効期限</label>
<input type="text" class="form-control" id="cc-expiration" placeholder="" required>
<div class="invalid-feedback">
有効期限を入力してください
</div>
</div>
<div class="col-md-3 mb-3">
<label for="cc-cvv">CVV</label>
<input type="text" class="form-control" id="cc-cvv" placeholder="" required>
<div class="invalid-feedback">
セキュリティコードを入力してください
</div>
</div>
</div>
<hr class="mb-4">
<button class="btn btn-primary btn-lg btn-block" type="submit">精算を続ける</button>
</form>
</div>
</div>
<footer class="my-5 pt-5 text-muted text-center text-small">
<p class="mb-1">© 2017-2019 会社名</p>
<ul class="list-inline">
<li class="list-inline-item"><a href="#">プライバシー</a></li>
<li class="list-inline-item"><a href="#">条項</a></li>
<li class="list-inline-item"><a href="#">サポート</a></li>
</ul>
</footer>
</div>
<script src="https://cdn.jsdelivr.net/npm/jquery@3.6.0/dist/jquery.slim.min.js" integrity="sha384-Qg00WFl9r0Xr6rUqNLv1ffTSSKEFFCDCKVyHZ+sVt8KuvG99nWw5RNvbhuKgif9z" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@4.6.2/dist/js/bootstrap.bundle.min.js" integrity="sha384-Fy6S3B9q64WdZWQUiU+q4/2Lc9npb8tCaSX9FK7E8HnRr0Jz8D6OP9dO5Vg3Q9ct" crossorigin="anonymous"></script>
//JavaScriptプラグインの設定など
</body>
</html>
// 無効なフィールドがある場合にフォーム送信を無効にするスターターJavaScriptの例
(function() {
'use strict';
window.addEventListener('load', function() {
// Bootstrapカスタム検証スタイルを適用してすべてのフォームを取得
var forms = document.getElementsByClassName('needs-validation');
// ループして帰順を防ぐ
var validation = Array.prototype.filter.call(forms, function(form) {
form.addEventListener('submit', function(event) {
if (form.checkValidity() === false) {
event.preventDefault();
event.stopPropagation();
}
form.classList.add('was-validated');
}, false);
});
}, false);
})();