デザイナーにも分かりやすいjQuery入門講座|jQueryの使い方

このエントリーをはてなブックマークに追加
索引
1章:短編集
2章:診断系コンテンツ
3章:製品抽出系コンテンツ
番外:Simulation Game

選択肢の作成(3)

概要

配列でラジオボタンのグループ毎にidを管理

複数のラジオボタンを管理するためには、ラジオボタンのグループ毎にidを管理しなければなりません。しかしselectIDの様な変数を複数用意するのでは効率が良くありません。そこで利用するのが配列です。このページでは配列を利用してラジオボタンのグループ毎にid情報を記憶するテクニックを学びます。

この項目は配列を良く理解していないと難しく感じると思います。配列に不慣れな方はあらかじめjavaScriptの配列について学んでおいて下さい。

解説

まずはhtmlの確認

サンプル(radio3/01.html)のソースを確認して、cssやjQueryには前回のサンプル(radio2/04.html)から変更がないことを確認して下さい。変更点は以下の様にラジオボタンのグループ(ul要素)が複数ある点だけです。区別しやすいようにul要素の間はhr要素で仕切っています。

<ul>
	<li id="0">軽くジョギングをする</li>
	<li id="1">ストレッチで目を覚ます</li>
	<li id="2">テレビで情報収集</li>
	<li id="3">遅刻しそうなので、すぐに出発</li>
	<li id="4">2度寝する</li>
</ul>
<hr/>
<ul>
	<li id="0">料理を作って本格朝食</li>
	<li id="1">パンとスープでシンプル朝食</li>
	<li id="2">サプリメントですませる</li>
	<li id="3">食べない</li>
	<li id="4">食べるどころか吐きそうだ...</li>
</ul>

各li要素に設定したid属性の値を確認して下さい。グループ毎に0〜4を設定しましたが、id属性はページ内に同じ物があってはいけないというcssのルールを破ってしまっています。同じidが複数あるため、jQueryも正常には機能せず最初のラジオボタンのグループ以外は機能しません。

なので、まずはli要素のid属性の値を設定し直す必要があります。

グループ毎にidを設定

サンプル(radio3/02.html)のソースを確認して、li要素のid属性の値が変更されていることを確認して下さい。radio3/01.htmlと異なり同じid属性の値はありません。

id属性の値はアンダースコア(_)を挟んだ2つの数値で構成され、左図のようなルールで命名されています。数値は配列での利用を考慮して0から始めます

この命名法を利用すれば、idの値によってli要素がどのグループの何番目の選択肢なのか分かるようになります。また、後でjQueryによってクリックした選択肢を確認しやすいように、li要素のテキストを変更しています。

<ul>
	<li id="0_0">グループ「0」の選択肢「0」</li>
	<li id="0_1">グループ「0」の選択肢「1」</li>
	<li id="0_2">グループ「0」の選択肢「2」</li>
	<li id="0_3">グループ「0」の選択肢「3」</li>
	<li id="0_4">グループ「0」の選択肢「4」</li>
</ul>
<hr/>		
<ul>
	<li id="1_0">グループ「1」の選択肢「0」</li>
	<li id="1_1">グループ「1」の選択肢「1」</li>
	<li id="1_2">グループ「1」の選択肢「2」</li>
	<li id="1_3">グループ「1」の選択肢「3」</li>
	<li id="1_4">グループ「1」の選択肢「4」</li>
</ul>

しかしjQueryは変更していないため、グループには対応しておらずページ全体で1つの選択しかできません。なので、次はjQueryを変更してグループ毎に選択肢を選択できるようにしていきます。

グループ毎の選択データを格納する配列を作成

サンプル(radio3/03.html)のソースを確認してhtmlには変更がないことを確認して下さい。jQueryは以下の様に変更され、クリック時のラジオボタンの処理を一旦削除しました。

var selectArray = [-1,-1,-1,-1,-1];		
$(function(){
	$("ul>li").click(function (){
		$(this).addClass("selected");
	});
});

そしてポイントは1行目に作成した配列selectArrayです。要素数はグループの数と同じ5つで、各要素には-1が設定してあります。最初は選択肢が選択されていないので、選択肢のidに存在していない-1を設定しているのです

情報をどのように格納するかというと、0番目の要素にグループ「0」で選択されたidを、1番目の要素にグループ「1」で選択されたidをといったように、各要素毎にグループで選択されたidを格納していきます。

クリックされたidをグループ番号と選択肢番号に分解

ではグループ毎に選択されたid番号を配列に格納していきましょう。しかし、その前にクリック時に取得されたidをグループ番号と選択肢番号に分解する必要があります。サンプル(radio3/04.html)のソースを確認してjQueryで、li要素がクリックされた時に以下の処理が追加されたことを確認して下さい。

var idArray = this.id.split("_");
var qID = Number(idArray[0]);
var ansID = Number(idArray[1]);
alert("グループ" + qID + "の選択肢" + ansID);

この処理はjQueryではなくjavaScriptの処理です。まず1行目でクリックされた要素のidを取得(例えば0_1)し、splitメソッドで「0」と「1」に分解します。splitで分解された値は配列になるので、[](配列アクセス演算子)で値を取得する必要があります。

2行目で配列アクセス演算子を利用して、分解された値の前半をグループ番号として変数「qID」に格納します。後半の「1」は選択された選択肢のidで、3行目で変数「ansID」に格納します。

注意点としては、idの値は文字列なのでNumberメソッドを利用して数値に変換しないといけません。でないと配列を操作する時に利用できません。そして最後にアラートで正しく値が取得できたかを確認しています。あとはこの2つの情報を利用して配列に格納するだけです。

配列に情報を格納

2つの情報を利用して配列に情報を格納するのは1行を追加するだけです。サンプル(radio3/05.html)のソースを確認し、li要素がクリックされた時に以下の処理が追加されたことを確認して下さい。

selectArray[qID] = ansID;
alert(selectArray);

配列selectArrayのqID(グループ番号)の位置にansID(選択肢番号)を設定するだけです。2行目で正しく配列が設定されたかを確認するためアラートで配列selectArrayを表示します。色々な選択肢をクリックして、指定されたグループの位置に選択肢のIDが格納されることを確認して下さい。

あとは、情報を基にラジオボタンの仕組みを作成するだけです。

ラジオボタンの完成

サンプル(radio3/06.html)のソースを確認し、li要素がクリックされた時に以下の処理が追加されたことを確認して下さい。まず1行目では現在選択されている選択肢の情報を配列「selectArray」から取り出して変数「selectID」に代入しています(selectIDは前回のシンプルなラジオボタンと同じように利用します)。

var selectID = selectArray[qID];//---選択されてたIDを取得
$("#" + qID + "_" + ansID).addClass("selected");
$("#" + qID + "_" + selectID).removeClass("selected");//---選択されてたラジオボタンを戻す

2行目と3行目は前回紹介したラジオボタンの仕組みと似ていますがセレクタの部分が異なります。これはli要素が「0_1」といったようにグループ番号と選択肢番号で構成されているためです。

クリックされた選択肢のidは変数「ansID」に代入されていますから2行目の処理で選択肢を選択状態に変更し、選択されていたidは変数「selectID」に代入されていますから3行目の処理で選択状態を解除します。

これでグループ毎にラジオボタンが機能するようになり完成したように見えますが、同じ選択肢をクリックすると選択が外れてしまいます(何度同じ選択肢をクリックしても選択されません)。チェックボックスであれば同じ選択肢をクリックしてON/OFFが切り替わるのですが、ラジオボタンであれば同じ選択肢をクリックしても選択が外れてはいけません。というわけで、この部分を修正します。

同じ選択肢がクリックされた時は処理をしない

radio3/06.htmlの問題を回避する考え方は「すでに選択されている選択肢がクリックされたら処理しない」です。サンプル(radio3/07.html)のソースを確認し、以下の処理が追加されていることを確認して下さい。

if (ansID == selectID) return;

クリックされた選択肢のid「ansID」と現在選択されている選択肢のid「selectID」を比較して、同じ場合はreturnで直ちにfunctionから抜けるようにしてあります。結果として、選択されている選択肢をクリックしても処理されなくなりました。

この処理を追加するのはラジオボタンの処理(addClassやremoveClassしている部分)よりも前です。また変数「selectID」を利用しているので、selectIDを作成している処理の後にしなければなりません。

これで診断系コンテンツで一番難しいラジオボタンの部分は完成です。次回は選択肢をクリックしたら自動的に次の問題に進む機能を作成します。

追記:余分な処理の削除(2013./25)

記事を見直していたら、不要になった処理を削除し忘れていたので追記しました。

サンプル(radio3/07b.html)を開いてjQueryが以下の様に変更されているのを確認して下さい。5行目の処理をコメントアウトしています。この処理は前回のサンプル(radio2/02.html)で説明した処理ですが、これは8行目の処理と同じ処理になります。

$("ul>li").click(function (){
	var idArray = this.id.split("_");
	var qID = Number(idArray[0]);
	var ansID = Number(idArray[1]);
	//$(this).addClass("selected")//---この行を削除;
	var selectID = selectArray[qID];
	if (ansID == selectID) return;
	$("#" + qID + "_" + ansID).addClass("selected");
	$("#" + qID + "_" + selectID).removeClass("selected");
	selectArray[qID] = ansID;
});

8行目の部分に5行目の処理を書いても機能します。5行目の方がシンプルに見えますが、8行目の方が9行目と対比して「新しいのを選択して、古いのを選択解除」していることが分かりやすいので、私はこちらの書き方を良くします。

次のページ以降、上記の5行目の処理は全て削除しました。