JavaScriptで複数のcheckboxの状態をチェックし、PHPで表示

人力検索はてなでの質問(http://www.hatena.ne.jp/1139557333)の回答を少し修正しました。PHPでデータを処理させる場合、配列になる項目のnameの末尾に括弧をつけておく必要があるのですが、これをJavaScriptで処理しようとするとちょっとややこしいのです。JavaScriptでは括弧を付けて明示的に配列にしているつもりでも、値が1個しかない場合には配列として扱われず、lengthなどのメソッドが使えないのです。そこで、値があるかないか、配列かどうか、と二重のチェックをする必要があります。これがちょっと面倒…。ここのサイト(http://web.paulownia.jp/script/tips/array.html)が参考になりました。
回答ではchecked状態になっているcheckboxの数を数える際、nameとcheckedを分けて以下のように記述していました。

if ((document.myForm.elements[i].name==”flag[]”) && (document.myForm.elements[i].checked)) {
    count ++;
}

ところが、よくよく調べてみると以下のような書き方が出来ることが分かりました。

if (document.myForm.elements['flag[]'][i].checked){
    count ++;
}

ソースはPHP-usersのログ(http://ns1.php.gr.jp/pipermail/php-users/2001-June/000215.html)です。やはり、JavaScriptPHPで同じことを悩んでいた先人がいたのですね。しみじみ。


書き直したソースは以下の通りです。コメントやHTML、PHPの出力部分なども少し修正しております。

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>JavaScriptで複数のcheckboxの状態をチェックし、PHPで表示するサンプル</title>
<script language="javascript">
<!--
function arraySizeCheck(){
//
// checkboxの個数をチェック
//
// (1) nameがflag[]の有無をチェック
//     falseの場合、checkboxが存在しない
//     return false;で終了し、その後の処理は行わない
// (2) nameがflag[]の配列のlengthをチェック
//     falseになる場合、配列ではない(要素が1つのみ)
//
    if (document.myForm.elements['flag[]']){
        if (document.myForm.elements['flag[]'].length){
            alert(document.myForm.elements['flag[]'].length+"個のcheckboxがあります。");
        }
        else{
            alert("1個のcheckboxがあります。");
        }
    }
    else{
        alert("checkboxが存在しません。");
        return false;
    }
//
// checked状態のcheckboxの個数をチェック
//
// (1) nameがflag[]の配列のlengthをチェック
//     elementsの中で、nameがflag[]であり、なおかつcheckedになっている
//     数だけcountを増加
// (2) flag[]が配列でない場合、要素が1つある、ない、のどちらかになる
//     checkedになっているかどうかを確認
//
    if (document.myForm.elements['flag[]'].length){
        count = 0;
        for (var i=0;i<document.myForm.elements['flag[]'].length;i++){
            if (document.myForm.elements['flag[]'][i].checked){
                count ++;
            }
        }
        alert(count+"個のcheckboxがチェックされています。");
    }
    else{
        if (document.myForm.elements['flag[]'].checked){
            alert("1個のcheckboxがチェックされています。");
        }
        else{
            alert("0個のcheckboxがチェックされています。");
            return false;
        }
    }
}
//-->
</script>
</head>
<body>
	<form name="myForm" action="<?php echo htmlspecialchars($_SERVER[’PHP_SELF’]);?>" method="POST">
		<label for="a">a : </label><input type="checkbox" name="flag[]" value="a" id="a">
		<label for="b">b : </label><input type="checkbox" name="flag[]" value="b" id="b">
		<label for="c">c : </label><input type="checkbox" name="flag[]" value="c" id="c">
		<label for="d">d : </label><input type="checkbox" name="flag[]" value="d" id="d">
		<label for="e">e : </label><input type="checkbox" name="flag[]" value="e" id="e">
		<input type="submit" value="check" onClick="arraySizeCheck()">
	</form>
<?php
	if ($_POST) {
		$flag = $_POST['flag'];
		foreach ($flag as $value) {
			print "<li>" . $value . " がチェックされました。\n";
		}
	}
?>
</body>
</html>

submitボタンのonClickにJavaScriptの関数を割り当ててますが、本当はonSubmitの方が良かったのかしら。JavaScriptでのチェックで1つもチェックされていない場合、PHPでの処理もさせずに終了、とかしたいんでしょうけど、上のサンプルだと無理ですよね。結局、PHPの処理部分で$_POSTが空の場合は何も出力しない、という形での実装になってしまっています。まぁ、その辺りはまた後で考えてみる、ということで。
それはそうと1つのファイル内にJavaScriptPHPのコードを書いてると、単純な変数の書き方も怪しくなってくるから不思議。$なしで変数呼び出そうとしちゃったりして。やっぱりJavaScriptは別ファイルにした方が良いな、という当たり前のことを初めて身をもって実感したbonlifeことジュンイチでした。