投稿日:2021年1月12日

Webの仕事をしていると、申し込みフォームを作る機会も多いと思います。
 
Googleフォーム Peatix など、無料でアンケートや申し込みフォームなどが作れる色々なサービスがあります。
しかし、回答条件によって、設問を変更する機能や、「その他」を選択したら入力欄を必須項目にする機能。
郵便番号から住所の自動入力、カナの自動入力など、より良いサービスやUXの向上を目指したカスタマイズが必要な場合もあります。
 
そんな中、下記のような要望がありました。

▲作成したフォームの一部分です。
※実際に動きます。
※送信をクリックしてもリセットされるだけで、送信はされません。
※当然、実際の案件のデータとは異なります。
 
仕様
A、B、Cのそれぞれのグループがあります。

 全てのグループ内で、どれか1つ以上選択することが必須。

 無選択で送信をクリックすると、アラートを表示させます。

 各グループ内で、どれか1つが選択できること。

 チェックしたら、他のチェックを外す。

 チェックするたびに合計が計算される。

※チェックボックスは複数チェックすることが可能ですが、今回は1つだけということでカスタマイズが必要。
※ラジオボタンは択一だけど、未選択にできないので使用できない。
これらを留意しながらの作成となりました。
 
ソースコードは下記。※CSSは省略します。
 
HTML

<!DOCTYPE html>
<html lang="ja">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>合計計算フォームテスト</title>
    <link rel="stylesheet" href="css/style.css">
    <script src="https://code.jquery.com/jquery-3.5.1.min.js"
        integrity="sha256-9/aliU8dGd2tb6OSsuzixeV4y/faTqgFtohetphbbj0=" crossorigin="anonymous"></script>
</head>

<body>
    <form action="" id="myForm">
        <table>
            <tr id="aGroup">
                <th>Aグループ</th>
                <td>
                    <label><input type="checkbox" name="a1" value="A-1 ¥1,000" class="checkbox">A-1 ¥1,000</label><br>
                    <label><input type="checkbox" name="a2" value="A-2 ¥2,000" class="checkbox">A-2 ¥2,000</label>
                </td>
            </tr>

            <tr id="bGroup">
                <th>Bグループ</th>
                <td>
                    <label><input type="checkbox" name="b1" value="B-1 ¥1,500" class="checkbox">B-1 ¥1,500</label><br>
                    <label><input type="checkbox" name="b2" value="B-2 ¥2,500" class="checkbox">B-2 ¥2,500</label><br>
                    <label><input type="checkbox" name="b3" value="B-3 ¥3,500" class="checkbox">B-3 ¥3,500</label>
                </td>
            </tr>

            <tr id="cGroup">
                <th>Cグループ</th>
                <td>
                    <label><input type="checkbox" name="c1" value="C-1 ¥2,500" class="checkbox">C-1 ¥2,500</label><br>
                    <label><input type="checkbox" name="c2" value="C-2 ¥3,500" class="checkbox">C-2 ¥3,500</label>
                </td>
            </tr>
        </table>
        合計:<input type="text" id="total" readonly="readonly"><br>
        <input type="submit" value="送信" id="submit">
    </form>

    <script src="js/index.js"></script>

</body>

</html>

▲ごく、ありふれたhtmlです。
trに付与したID値と、それぞれのclass値のcheckboxをJavaScriptで操作します。
 
JavaScript

//////////////////////////////////////////////////////
// ▼▼▼ 各グループのチェックボックスを1つだけ選択できるようにする
onlyOneCheck('#aGroup .checkbox');
onlyOneCheck('#bGroup .checkbox');
onlyOneCheck('#cGroup .checkbox');

function onlyOneCheck(target) {
    $(target).click(function () {
        if ($(this).prop('checked')) {
            $(target).prop('checked', false); // 一度全てのチェックを外す
            $(this).prop('checked', true); // 自分のチェックを入れる
        }
    });
}

//////////////////////////////////////////////////////
// ▼▼▼ 各グループでのチェックボックス値を取得
// Aグループ
var aGroupPrice = 0; // 初期値は0 この設定がないとチェックなしの0が取得できない
$('#aGroup').change(function () {
    if ($('#aGroup .checkbox').is(':checked')) {
        var aGroupPriceVal = $('#aGroup .checkbox:checked').val(); // チェックした値を取得
        if (aGroupPriceVal == "A-1 ¥1,000") { // 値によって金額を設定
            aGroupPrice = 1000; // グルーバル変数でないと外から参照できない
        } else if (aGroupPriceVal == "A-2 ¥2,000") {
            aGroupPrice = 2000;
        }
    } else {
        aGroupPrice = 0;
    }
});

// Bグループ
var bGroupPrice = 0; // 初期値は0 この設定がないとチェックなしの0が取得できない
$('#bGroup').change(function () {
    if ($('#bGroup .checkbox').is(':checked')) {
        var bGroupPriceVal = $('#bGroup .checkbox:checked').val(); // チェックした値を取得
        if (bGroupPriceVal == "B-1 ¥1,500") { // 値によって金額を設定
            bGroupPrice = 1500; // グルーバル変数でないと外から参照できない
        } else if (bGroupPriceVal == "B-2 ¥2,500") {
            bGroupPrice = 2500;
        } else if (bGroupPriceVal == "B-3 ¥3,500") {
            bGroupPrice = 3500;
        }
    } else {
        bGroupPrice = 0;
    }
});

// Cグループ
var cGroupPrice = 0; // 初期値は0 この設定がないとチェックなしの0が取得できない
$('#cGroup').change(function () {
    if ($('#cGroup .checkbox').is(':checked')) {
        var cGroupPriceVal = $('#cGroup .checkbox:checked').val(); // チェックした値を取得
        if (cGroupPriceVal == "C-1 ¥2,500") { // 値によって金額を設定
            cGroupPrice = 2500; // グルーバル変数でないと外から参照できない
        } else if (cGroupPriceVal == "C-2 ¥3,500") {
            cGroupPrice = 3500;
        }
    } else {
        cGroupPrice = 0;
    }
});

//////////////////////////////////////////////////////
// ▼▼▼ 合計を計算
$('#aGroup,#bGroup,#cGroup').change(function () {
    $('#total').val(aGroupPrice + bGroupPrice + cGroupPrice);
});

//////////////////////////////////////////////////////
// ▼▼▼ 全てのグループがチェックされてなかったらアラートを表示
$('#myForm').submit(function () {
    var aGroupLen = ($('#aGroup .checkbox:checked').length);
    var bGroupLen = ($('#bGroup .checkbox:checked').length);
    var cGroupLen = ($('#cGroup .checkbox:checked').length);
    if ((aGroupLen + bGroupLen + cGroupLen) < 1) {
        alert("最低、1つ選択してください。");
        return false;
    } else {
        $('#myForm').submit();
    }
});

▲仕様に沿って、
 チェックの動作。
 チェックされたものから金額を取得。
 合計値の表示。
 チェックが皆無の場合のアラート表示。
のロジックが書かれています。
 
チェックの動作。

//////////////////////////////////////////////////////
// ▼▼▼ 各グループのチェックボックスを1つだけ選択できるようにする
onlyOneCheck('#aGroup .checkbox');
onlyOneCheck('#bGroup .checkbox');
onlyOneCheck('#cGroup .checkbox');

function onlyOneCheck(target) {
    $(target).click(function () {
        if ($(this).prop('checked')) {
            $(target).prop('checked', false); // 一度全てのチェックを外す
            $(this).prop('checked', true); // 自分のチェックを入れる
        }
    });
}

▲上記の9行目。

if ($(this).prop('checked')) {

クリックするとチェックボックスのプロパティを取得します。
チェックされているとtrueが、されてないとfalseが返ります。
コメントにもあるように、

$(target).prop('checked', false);

で一度全てのチェックを外し、

$(this).prop('checked', true);

でチェックを入れるようにしています。
関数化しているので、それぞれのグループの.checkbox に実行するようにしています。
 
チェックされたものから金額を取得。

// Aグループ
var aGroupPrice = 0; // 初期値は0 この設定がないとチェックなしの0が取得できない
$('#aGroup').change(function () {
    if ($('#aGroup .checkbox').is(':checked')) {
        var aGroupPriceVal = $('#aGroup .checkbox:checked').val(); // チェックした値を取得
        if (aGroupPriceVal == "A-1 ¥1,000") { // 値によって金額を設定
            aGroupPrice = 1000; // グルーバル変数でないと外から参照できない
        } else if (aGroupPriceVal == "A-2 ¥2,000") {
            aGroupPrice = 2000;
        }
    } else {
        aGroupPrice = 0;
    }
});

 

var aGroupPrice = 0; // 初期値は0 この設定がないとチェックなしの0が取得できない

▲コメントにもあるように、これを記載せずに、チェックをしなかった場合undefinedが返ります。
例えば、Aグループで何もチェックせずに、Bグループ以降をチェックした場合、変数aGroupPriceには何も入らないので、undefinedが返ります。
合計にはNaNと入力されます。

$('#aGroup').change(function () {

changeイベントで、グループ内でチェックされたら設定された金額を取得するようにしています。

if ($('#aGroup .checkbox').is(':checked')) {

▲チェックされたら

var aGroupPriceVal = $('#aGroup .checkbox:checked').val();

▲チェックされたvalueを変数に代入。

if (aGroupPriceVal == "A-1 ¥1,000") { // 値によって金額を設定
            aGroupPrice = 1000; // グルーバル変数でないと外から参照できない
        } else if (aGroupPriceVal == "A-2 ¥2,000") {
            aGroupPrice = 2000;
        }

▲金額の出し分け。
aGroupPriceは関数外で使用する変数なのでグルーバル変数にする必要があります。

} else {
        aGroupPrice = 0;
    }

▲チェックを外した場合は「0」に設定。
Bグループ、Cグループも同じロジックです。
 

//////////////////////////////////////////////////////
// ▼▼▼ 合計を計算
$('#aGroup,#bGroup,#cGroup').change(function () {
    $('#total').val(aGroupPrice + bGroupPrice + cGroupPrice);
});

▲これは、記載してある通りです。
A、B、Cグループの変化をchangeイベントで取得し、合計を表示する#totalに表示するようにしています。
 

//////////////////////////////////////////////////////
// ▼▼▼ 全てのグループがチェックされてなかったらアラートを表示
$('#myForm').submit(function () {
    var aGroupLen = ($('#aGroup .checkbox:checked').length);
    var bGroupLen = ($('#bGroup .checkbox:checked').length);
    var cGroupLen = ($('#cGroup .checkbox:checked').length);
    if ((aGroupLen + bGroupLen + cGroupLen) < 1) {
        alert("最低、1つ選択してください。");
        return false;
    } else {
        $('#myForm').submit();
    }
});
$('#myForm').submit(function () {

submitがクリックされた場合の処理。
A、B、Cの各グループのチェックされた数を取得し、1未満(0)だった場合アラートを表示し、処理から外れます。
1以上だった場合、submit処理を行います。
 

まとめ

冒頭でも触れましたが、無料のサービスが充実してきている昨今。
お客さまの要望や、より良いUX、UI、サービス向上のためのカスタマイズは非常に重要です。
さらに、技術習得に励みたいと思います。
 
掲載しているソースコードはご自由にお使いいただいても構いませんが、何かあっても責任は追いかねるのでご了承ください。
 
最後まで読んでくださりありがとうございました。
 

関連記事



 

Pocket