セレクトボックスの選択肢を連動させる(改)
以前の[id:Mug:20060414#1145023696]において作成していたスクリプトを改造しました。
デフォルト選択について、次のようなロジックを入れました。
- 指定された値をデフォルト選択可能にした。
- 指定が無い場合は、現在の値をなるだけ引き継ぐようにした。
Select.js(Shift_JIS)
/**
* 選択肢クラス
* @param parentValue 親の値(null:いつでも表示)
* @param text 表示テキスト
* @param value 値
* @param style CSS(省略可)
*/
function SelectOption(parentValue, text, value, style) {
this.parentValue = parentValue;
this.setOption = function() {
this.text = text;
this.value = value;
if(style) {
this.style.cssText = style;
}
};
return this;
}/**
* セレクトボックスクラス
* @param id セレクトボックスID
*/
function SelectBox(id) {
/**
* IDに対応オブジェクトを取得
* @return オブジェクトorNULL
*/
function getObject() {
var obj = document.getElementById(id);
if(!obj.options && ( (typeof obj.length) == "number") ) {
if(obj.length > 0) {
obj = obj[0];
} else {
obj = null;
}
}
return obj;
}
// オプションのリスト
var options = [];
/**
* オプション登録
* @param condition 表示条件
*/
this.registOption = function(option) {
options[options.length] = option;
};
// 子のオブジェクト
var child = null;
/**
* 子のオブジェクトを設定する
* @param childObj 子のオブジェクト
*/
this.setChild = function(childObj) {
child = childObj;
};
/**
* オプション反映
* @param parentValue 親の値(null:全部表示)
* ※比較に==を使っているのでundefinedもnullと等しく扱われる。
* @params [defaultValues] 自身以下のデフォルト値(配列または可変数引数)
* 例えば自身から孫までの値を設定するならば、
* xxx.make(null, ["自身の値", "子の値", "孫の値"]); でもよいし、
* xxx.make(null, "自身の値", "子の値", "孫の値" ); でもよい。
*/
this.make = function(parentValue, defaultValues) {
var obj = getObject();
if(obj) {
// デフォルト値調整
var defVals;
switch(arguments.length) {
case 0:
case 1:
defVals = [];
break;
case 2:
if(defaultValues instanceof Array) {
defVals = defaultValues;
} else if(defaultValues && ( (typeof defaultValues) == "object") && ( (typeof defaultValues.length) == "number") ) {
defVals = defaultValues;
} else {
defVals = [defaultValues];
}
break;
default:
defVals = Function.prototype.call.apply(function() { return arguments; }, arguments);
}
// 選択すべき値
var vals = {};
if(defVals.length > 0) {
vals[ defVals[0] ] = true;
defVals = Function.prototype.call.apply(function() { return arguments; }, defVals);
} else {
for(var i = 0; i < obj.options.length; i++) {
if(obj.options[i].selected) {
vals[obj.options[i].value] = true;
}
}
}
// 選択肢削除
obj.options.length = 0;
// 表示すべき選択肢抽出
var opt = (parentValue != null) ? [] : options;
if(parentValue != null) {
for(var i = 0; i < options.length; i++) {
if( (options[i].parentValue == null) || (options[i].parentValue == parentValue) ) {
opt[opt.length] = options[i];
}
}
}
// 選択肢反映
obj.options.length = opt.length;
for(var i = 0; i < opt.length; i++) {
opt[i].setOption.call(obj.options[i]);
obj.options[i].selected = (vals.hasOwnProperty(obj.options[i].value) && vals[obj.options[i].value]);
}
// 子のオブジェクトにも連鎖反映
if(child) {
child.make(obj.value, defVals);
}
}
};
return this;
}
HTMLファイル(使用例)
<html>
<head>
<title>セレクトボックス親子関係</title>
<script type="text/javascript" src="Select.js" charset="Shift_JIS"></script>
<script type="text/javascript"><!--var box1 = new SelectBox("sb1");
box1.registOption(new SelectOption(null, "都道府県", "0", "color:gray;"));
box1.registOption(new SelectOption(null, "東京都" , "1"));
box1.registOption(new SelectOption(null, "神奈川県", "2"));
box1.registOption(new SelectOption(null, "埼玉県" , "3"));
box1.registOption(new SelectOption(null, "千葉県" , "4"));
var box2 = new SelectBox("sb2");
box2.registOption(new SelectOption(null, "区市町村", "0", "color:gray;"));
box2.registOption(new SelectOption("1" , "千代田区", "1"));
box2.registOption(new SelectOption("1" , "中央区" , "2"));
box2.registOption(new SelectOption("2" , "横浜市" , "3"));
box2.registOption(new SelectOption("2" , "川崎市" , "4"));
box2.registOption(new SelectOption("3" , "与野市" , "5"));
box2.registOption(new SelectOption("4" , "千葉市" , "6"));
var box3 = new SelectBox("sb3");
box3.registOption(new SelectOption(null, "詳細" , "0", "color:gray;"));
box3.registOption(new SelectOption("1" , "一番町" , "1"));
box3.registOption(new SelectOption("3" , "みなとみらい", "2"));
box3.registOption(new SelectOption("6" , "マリンスタジアム", "3"));
box1.setChild(box2);
box2.setChild(box3);
window.onload = function() {
box1.make(null, "2", "3");
};
//--></script>
</head>
<body>
<form>
<select id="sb1" onchange="box2.make(this.value);"></select>
<select id="sb2" onchange="box3.make(this.value);"></select>
<select id="sb3"></select>
</form>
</body>
</html>
このように、boxObj.make(親の値, 自身の値, 子の値, 孫の値, ...);とすることで、デフォルト値を設定可能としました。