チェックボックスをチェック(checked)かつ選択不可(disabled)にする時の問題点と対処法

最近、チェックボックスをチェック(checked)かつ選択不可(disabled)にするというケースがありました。その時の問題点と対処法について書きます。

単純にchecked、disabled両方記述するだけではダメ

単純に「inputタグのtype属性がcheckboxのものに対してcheckedとdisabledを両方記述すればいいのでは?」と考えたのですが、これでは問題があります。

なぜ問題があるのか?

disabled属性とreadonly属性

まず、フォームタグの値を選択不可(編集不可)にするには、属性にdisabledもしくはreadonlyを指定する必要があります。

disabled属性
フォームタグの値は選択不可(編集不可)となり、フォームタグの値を送信しない。

readonly属性
フォームタグの値は選択不可(編集不可)となるが、フォームタグの値は送信する。

つまり、disabledの状態だとたとえcheckedを記述しても値(value)が送信されないのです。

では、readonly属性とchecked属性の組み合わせはどうでしょう?
残念ながらこれも間違いです。readonly属性ははチェックボックスには対応していないのです。readonlyとcheckedを両方記述しても、普通の選択可能なチェックボックスと同じになります。

チェック(checked)かつ選択不可(disabled)を実現するには?

チェックボックスをチェック(checked)かつ選択不可(disabled)にしてかつ値を送信するには、JavaScript(jQuery)を使用します。

やることは単純で、選択されたチェックボックスに対してchecked、disabledの両方の属性を指定します。加えて、値を送信するために、チェックボックスとは別にinputタグでtype属性がhiddenのものを追加します。

実際にサンプルを用意したので確認してみてください。

サンプルとソースコードで確認

まずはDEMOをクリックしてサンプルで動作を確認してください。

下記のような動作を実現しています。

DEMO

  • タイプ1、タイプ2のラジオボタンをクリック
    チェックボックス6を選択不可(disabled)にする
  • タイプ3、タイプ4のラジオボタンをクリック
    チェックボックス6をチェック(checked)かつ選択不可(disabled)にする

また、ページリロード毎にタイプ1~4をランダムで選択するようにしています。

htmlでコーディング

まずはhtmlでコーディングします。

<div id="checkbox_chk_dab">
	<form method="post" name="chk_dab_form">
		<div class="input_item1">
			<ul>
				<li>
					<input type="radio" id="type1" name="type" value="1">
					<label for="type1">タイプ1</label>
				</li>
				<li>
					<input type="radio" id="type2" name="type" value="2">
					<label for="type2">タイプ2</label>
				</li>
				<li>
					<input type="radio" id="type3" name="type" value="3">
					<label for="type3">タイプ3</label>
				</li>
				<li>
					<input type="radio" id="type4" name="type" value="4">
					<label for="type4">タイプ4</label>
				</li>
			</ul>
		</div>
		<div class="input_item2">
			<ul>
				<li>
					<input type="checkbox" id="s_type1" name="s_type1" value="1">
					<label for="s_type1">チェックボックス1</label>
				</li>
				<li>
					<input type="checkbox" id="s_type2" name="s_type2" value="2">
					<label for="s_type2">チェックボックス2</label>
				</li>
				<li>
					<input type="checkbox" id="s_type3" name="s_type3" value="3">
					<label for="s_type3">チェックボックス3</label>
				</li>
				<li>
					<input type="checkbox" id="s_type4" name="s_type4" value="4">
					<label for="s_type4">チェックボックス4</label>
				</li>
				<li>
					<input type="checkbox" id="s_type5" name="s_type5" value="5">
					<label for="s_type5">チェックボックス5</label>
				</li>
				<li>
					<input type="checkbox" id="s_type6" disabled name="s_type6" value="6">
					<label for="s_type6">チェックボックス6</label>
				</li>
			</ul>
		</div>
	</form>
</div>

上部にラジオボタン、下部にチェックボックスを並べて、選択したラジオボタンに応じてチェックボックスの状態を変化させます。
ラジオボタン、チェックボックスの値はそれぞれ連番が割り振っています。

今回はチェックボックス6は常にdisabled状態になるので、初めからinputタグにdisabledを記述しておきます。

CSSで見た目を整える

CSSで見た目を整えます(CSSについては、特別なことはしていません。個人で自由に指定してください。)。

#checkbox_chk_dab {
	width: 500px;
}

#checkbox_chk_dab .input_item1 ul {
	margin:0 0 25px 0;
}
#checkbox_chk_dab .input_item1 ul li{
	display: inline-block;
	margin:0 10px 0 0;
	font-size:18px;
}
#checkbox_chk_dab .input_item2 ul li {
	display: inline-block;
	margin: 0 30px 10px 0;
}

#checkbox_chk_dab input {
	width: 18px;
	height: 18px;
	vertical-align: middle;
}

JavaScript(jQuery)で動きをつける

JavaScript(jQuery)を使用して、実際に動きをつけます(jQueryを読み込んでください)

	// 1.ページ読み込み時の処理
$(document).ready(function(){
	var rand = Math.floor(Math.random() * 4) + 1;
	var type = '#type' + rand;

	$(type).prop('checked', true);
	check_disabled();
});

// 2.ラジオボタン選択時の処理
$(function(){
	$('input:radio[name="type"]').click(function(){
		check_disabled();
	});
});

// 3.checked、disabled属性の付与・削除処理
function check_disabled(){
	if($('#type3').prop('checked') || $('#type4').prop('checked')){
		$('#s_type6').prop('checked', true);
		$('#s_type6').prop('disabled', true);
		$('#s_type6').next('label').css('color', '#000000');

		if($('input:hidden[name="s_type6"]').length == 0){
			$('#s_type6').after('<input type="hidden" name="s_type6" value="6" />');
		}
	}else{
		$('#s_type6').prop('checked', false);
		$('#s_type6').parent().find('label').css('color', '#bbbbbb');
		$('input:hidden[name="s_type6"]').remove();
	}
}

タイプ1、タイプ2のラジオボタンをクリックしたら、チェックボックス6を選択不可(disabled)にする
タイプ3、タイプ4のラジオボタンをクリックしたら、チェックボックス6をチェック(checked)かつ選択不可(disabled)にする

1.ページ読み込み時の処理

ページ読み込みの時に、.prop()を使ってタイプ1~4のラジオボタンをランダムで選択させています。

ラジオボタンが選択されたら、check_disabled()関数でチェックボックスの制御をします。

●rand
1~4までのランダムな数字を生成します。
Math.floor(val)を使って小数点切り捨てます。Math.random()は0以上1未満の乱数を返します。

●type
選択するid名の生成

2.ラジオボタン選択時の処理

.click()を使ってマウスクリックでラジオボタン選択時の処理を行います。ここでもページ読み込み時と同様にcheck_disabled()関数を使用しています。

3.checked、disabled属性の付与・削除処理

check_disabled()関数でチェックボックスの制御を行います。

タイプ3もしくはタイプ4がchecked状態のとき
チェックボックス6をchecked、disabledにします。
.after()でチェックボックスの後ろにチェックボックス6と同じ値をもつinputタグ(type:hidden)を追加します。

タイプ1もしくはタイプ2checked状態の時
チェックボックス6のchecked状態を解除します。
タイプ3もしくはタイプ4がchecked状態のときに追加したinputタグ(type:hidden)を.remove()で削除します。

まとめ

いかがでしたか?disabledで値が送信されないなら別で値を持ったタグを追加してしまおうという単純な仕組みでした。

  • フォームタグを編集不可にするときはdisabledもしくはreadonly属性にする
  • チェックボックス、ラジオボタンなどはreadonlyが使えない
  • 実際に表示されるinputタグと送信する値を持たせるインプットタグを別々に用意する

大きなポイントはこんな感じです。

inputタグの中でもタイプがtext、numberのものやtextareaタグなどはreadonlyが有効なので、readonlyが使用可能なものはそちらを使ったほうが無駄なコードが省けます。

CONTACTお問い合わせ

まずはお気軽にご相談ください

お問い合わせ