セレクトボックス同士の連動
セレクトボックスのある値を選択すると、別のセレクトボックスがその値に応じて内容が変わるスクリプトをご紹介します。
ここでご紹介するセレクトボックスの連動は、1対1を対象としています。
元のセレクトボックスのvalue属性値とoptgroupのlabel属性値を比較して一致したものを表示するような仕組みです。
デモ
関数定義とHTMLの準備
関数定義
JavaScript
var linkedSelect = function() {
this.init.apply(this, arguments);
};
linkedSelect.prototype = {
settings : {},
elements : {},
data : {},
init : function(settings) {
settings = this.arrayMerge({
actionTargetName : '',
changeTargetName : '',
stockFirstElement : true
}, settings);
this.settings = settings;
this.data = {
activeIndex : 0
};
if (settings.actionTargetName && settings.changeTargetName) {
this.setup();
}
return this;
},
setup : function() {
var actionTargetElements = document.getElementsByName(this.settings.actionTargetName),
changeTargetElements = document.getElementsByName(this.settings.changeTargetName);
if (actionTargetElements.length > 0 && changeTargetElements.length > 0) {
var actionTargetElement = actionTargetElements[0],
changeTargetElement = changeTargetElements[0],
optionGroups = changeTargetElement.getElementsByTagName('optgroup'),
optionElementObjs = [],
optionElements = [],
optionCloneElements = [],
attrNode = null,
selectIndex = 0,
ii = 0,
len2 = 0;
for (var i = 0, len = optionGroups.length; i < len; i++) {
optionElements = optionGroups[i].getElementsByTagName('option');
optionCloneElements = [];
selectIndex = 0;
for (ii = 0, len2 = optionElements.length; ii < len2; ii++) {
attrNode = optionElements[ii].getAttributeNode('selected');
if (attrNode) {
selectIndex = ii;
optionElements[ii].removeAttribute(attrNode);
}
optionCloneElements.push(optionElements[ii].cloneNode(true));
}
optionElementObjs.push({
label : optionGroups[i].label,
elements : optionCloneElements,
selectIndex : selectIndex
});
}
var stockFirstElement = changeTargetElement.getElementsByTagName('option')[0].cloneNode(true);
changeTargetElement.innerHTML = '';
if (this.settings.stockFirstElement) {
changeTargetElement.appendChild(stockFirstElement);
}
this.elements = {
changeTargetElement : changeTargetElement,
actionTargetElement : actionTargetElement,
optionElements : optionElementObjs
};
this.addEvent();
this.changeOption();
}
return this;
},
addEvent : function() {
var self = this;
if (!this.elements.actionTargetElement) return this;
this.elements.actionTargetElement.onchange = function() {
self.changeOption();
};
return this;
},
changeOption : function() {
if (this.elements.actionTargetElement && this.elements.changeTargetElement && this.elements.optionElements) {
var actionTargetElement = this.elements.actionTargetElement,
changeTargetElement = this.elements.changeTargetElement,
optionElements = this.elements.optionElements,
oldSelectIndex = this.data.activeIndex,
selectIndex = actionTargetElement.selectedIndex,
changeTargetSelectIndex = changeTargetElement.selectedIndex,
options = actionTargetElement.options,
selectValue = options[selectIndex].value,
setSelected = 0,
oldOptionElements = null,
stockFirstElement = '',
setOptions = [],
i = 0,
len = 0;
this.data.activeIndex = selectIndex;
if (this.settings.stockFirstElement) {
stockFirstElement = changeTargetElement.getElementsByTagName('option')[0].cloneNode(true);
changeTargetElement.innerHTML = '';
changeTargetElement.appendChild(stockFirstElement);
oldSelectIndex--;
} else {
changeTargetElement.innerHTML = '';
}
if (oldSelectIndex > -1) {
oldOptionElements = optionElements[oldSelectIndex];
oldOptionElements.selectIndex = changeTargetSelectIndex;
}
if (selectValue !== '') {
for (i = 0, len = optionElements.length; i < len; i++) {
if (optionElements[i].label === selectValue) {
setSelected = optionElements[i].selectIndex;
setOptions = optionElements[i].elements;
break;
}
}
for (i = 0, len = setOptions.length; i < len; i++) {
changeTargetElement.appendChild(setOptions[i]);
}
changeTargetElement.selectedIndex = setSelected;
}
}
return this;
},
arrayMerge : function() {
var key, result = false;
if (arguments && arguments.length > 0) {
result = {};
for (var i = 0, len = arguments.length;i < len; i++) {
if (arguments[i] && typeof arguments[i] === 'object') {
for (key in arguments[i]) {
if (isFinite(key)) {
result.push(arguments[i][key]);
} else {
result[key] = arguments[i][key];
}
}
}
}
}
return result;
}
};
HTMLの準備
label属性には切り替え元のターゲットであるoptionのvalue値を指定します。
<p><select name="sample-linked-select1">
<option value="select 1">select 1</option>
<option value="select 2">select 2</option>
<option value="select 3">select 3</option>
<option value="select 4">select 4</option>
<option value="select 5">select 5</option>
</select> <select name="sample-linked-select2">
<optgroup label="select 1">
<option value="select 1-1">select 1-1</option>
<option value="select 1-2">select 1-2</option>
<option value="select 1-3">select 1-3</option>
<option value="select 1-4">select 1-4</option>
<option value="select 1-5">select 1-5</option>
</optgroup>
<optgroup label="select 2">
<option value="select 2-1">select 2-1</option>
<option value="select 2-2">select 2-2</option>
<option value="select 2-3">select 2-3</option>
<option value="select 2-4">select 2-4</option>
<option value="select 2-5">select 2-5</option>
</optgroup>
<optgroup label="select 3">
<option value="select 3-1">select 3-1</option>
<option value="select 3-2">select 3-2</option>
<option value="select 3-3">select 3-3</option>
<option value="select 3-4">select 3-4</option>
<option value="select 3-5">select 3-5</option>
</optgroup>
<optgroup label="select 4">
<option value="select 4-1">select 4-1</option>
<option value="select 4-2">select 4-2</option>
<option value="select 4-3">select 4-3</option>
<option value="select 4-4">select 4-4</option>
<option value="select 4-5">select 4-5</option>
</optgroup>
<optgroup label="select 5">
<option value="select 5-1">select 5-1</option>
<option value="select 5-2">select 5-2</option>
<option value="select 5-3">select 5-3</option>
<option value="select 5-4">select 5-4</option>
<option value="select 5-5">select 5-5</option>
</optgroup>
</select></p>
使い方
構文
var instance = new linkedSelect(options);
引数
引数名 | 型 | 説明 | |
---|---|---|---|
第一引数 必須 |
options | object | 各種設定 オプションを参照 |
オプション
設定値 | 初期値 | 説明 |
---|---|---|
actionTargetName | '' | アクションを起こすセレクトボックスのname属性値 |
changeTargetName | '' | option要素を切り替えるセレクトボックスのname属性値 |
stockFirstElement | true | option要素を切り替えるセレクトボックスの最初の要素を維持するかどうか |
サンプルコード
var linkedSelectObj = new linkedSelect({
actionTargetName : 'first',
changeTargetName : 'sub'
});