<optgroup label="SHARP"> <option>MZ-80K</option> <option class="selected">MZ-700</option> <option>MZ-2500</option> </optgroup> <optgroup label="NEC"> <option>PC-6001</option> <option>PC-8001</option> <option class="selected">PC-9801</option> <option>PC-9821</option> </optgroup>と、class="selected" を与えておく。これを初期選択項目と考える。
select.selectedIndex = 0;の一文がある。これが初期選択される option 要素の番号だ。現在は 0 番目、つまり最初のもので固定されている。ここに、0 ではなく、class="selected" を持つ option 要素の番号を入れてやれば良い。
function filterSelects (select) {
//...snip...
while (i < I) {
var label = clone.options[ clone.selectedIndex ].text;
var clone = recoverControl (form, RelationOrder[i++]);
filterOptions (clone, label);
}
}
function filterOptions (select, label) {
//...snip...
select.selectedIndex = getIndexOfSelectedOption (select);
}
function getIndexOfSelectedOption (select) {
var options = select.getElementsByTagName ('option');
for (var i = options.length; --i; ) {
if (/ selected /.test (' ' + options[i].className + ' ')) break;
}
return i;
}<?xml version="1.0" encoding="Shift_JIS"?>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Test</title>
<style type="text/css">
[disabled] {
display: none;
}
</style>
<script type="application/javascript; version=1.6"><![CDATA[
if (document.implementation &&
document.implementation.hasFeature ('XHTML' , '2.0') &&
document.implementation.hasFeature ('HTMLEvents', '2.0') &&
document.implementation.hasFeature ('XPath' , '3.0') &&
true)
(function () {
/************************************************************************/
// bootstrapping
window.___HTMLSelectElementLinkageRegistry___ = {
bootstrap : {
handleEvent : function (event) {
var form = document.getElementsByTagNameNS ('http://www.w3.org/1999/xhtml', 'form')[0];
if (form) {
var first = initLinkage.call (form, 'input.data1', 'input.data2', 'input.data3', 'input.data4');
if (first) {
dispatchChangeEvent.call (first);
}
}
}
},
termination : {
handleEvent : function (event) {
var r = ___HTMLSelectElementLinkageRegistry___;
removeEventListener ('load' , r.bootstrap , false);
removeEventListener ('unload', r.termination, false);
delete ___HTMLSelectElementLinkageRegistry___;
}
}
};
window.r = ___HTMLSelectElementLinkageRegistry___;
addEventListener ('load' , r.bootstrap , false);
addEventListener ('unload', r.termination, false);
delete r;
////////////////////////////////////////////////////////////////////////
// extends EventTarget
function dispatchChangeEvent () {
var event = this.ownerDocument.createEvent ('HTMLEvents');
event.initEvent ('change', true, false);
return this.dispatchEvent (event);
}
// extends HTMLElement
function getSingleElement (elementName) {
var expression = 'descendant::*[ local-name() = "' + elementName + '" and namespace-uri() = "http://www.w3.org/1999/xhtml"]';
var context = this;
var resolver = this.ownerDocument.createNSResolver (this);
var type = XPathResult.FIRST_ORDERED_NODE_TYPE;
return function (/*xpath-predicate-list*/) {
var I = arguments.length;
var i = 0;
while (i < I) {
var expr = expression.concat ('[', arguments[i++], ']');
var node = document.evaluate (expr, context, resolver, type, null).singleNodeValue;
if (node) return node;
}
return null;
};
}
// extends HTMLFormElement
function initLinkage (/*name-list*/) {
if (this.isSupported ('HTML', '2.0')) {
Array.forEach (arguments, function (name, index, nameList) {
var node = this.elements[name];
var nextName = nameList[index + 1];
var nextNode = this.elements[nextName];
if (node && nextName) {
node.addEventListener ('change', {
nextNode : nextNode,
handleEvent : function (event) {
synchronize.call (event.target, this.nextNode);
}
}, false);
}
node = nextName = nextNode = null;
}, this);
return this.elements[ arguments[0] ];
} else {
return null;
}
}
// extends HTMLSelectElement
function synchronize (other /*htmlSelectElement*/) {
var label = this.options[ this.selectedIndex ].text;
var optgroups = other.getElementsByTagNameNS ('http://www.w3.org/1999/xhtml', 'optgroup');
var optgroup = enableGroup.call (optgroups, label)[0];
var option;
if (optgroup) {
option = getSingleElement.call (optgroup, 'option')(
'contains( " selected ", concat( " ", normalize-space( @class), " "))',
'position() = 1'
);
}
other.selectedIndex = option ? option.index : 0;
dispatchChangeEvent.call (other);
}
// interface HTMLOptGroupsCollection
function enableGroup (label) {
var result = [ ];
Array.forEach (this, function (optgroup) {
if (! (optgroup.disabled = (optgroup.label != label))) {
result.push (optgroup);
}
} );
return result;
};
/************************************************************************/
} )();
]]></script>
</head>
<body>
<form action="#">
<p>
<select name="input.data1">
<option>-</option>
<option>SHARP</option>
<option selected="selected">NEC</option>
<option>FUJITSU</option>
</select>
<select name="input.data2">
<option>-</option>
<optgroup label="SHARP">
<option>MZ-80K</option>
<option class="selected">MZ-700</option>
<option>MZ-2500</option>
</optgroup>
<optgroup label="NEC">
<option>PC-6001</option>
<option>PC-8001</option>
<option class="selected">PC-9801</option>
<option>PC-9821</option>
</optgroup>
<optgroup label="FUJITSU">
<option>FM-8</option>
<option>FM-7</option>
<option>FM-11</option>
<option>FM-77AV</option>
</optgroup>
</select>
<select name="input.data3">
<option>-</option>
<optgroup label="MZ-700">
<option>あいうえお</option>
<option>かきくけこ</option>
</optgroup>
<optgroup label="PC-9801">
<option>さしすせそ</option>
<option class="selected">たちつてと</option>
</optgroup>
<optgroup label="FM-77AV">
<option>なにぬねの</option>
</optgroup>
</select>
<select name="input.data4">
<option>-</option>
<optgroup label="たちつてと">
<option>はひふへほ</option>
<option>まみむめも</option>
</optgroup>
<optgroup label="なにぬねの">
<option>やゆよ</option>
<option>らりるれろ</option>
<option>わをん</option>
</optgroup>
</select>
</p>
</form>
</body>
</html><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<title>Test</title>
<script type="text/javascript">
if (document.implementation &&
document.implementation.hasFeature ('HTML', '1.0') &&
typeof Function.prototype != 'undefined' &&
typeof Function.prototype.call != 'undefined' &&
true)
(function () {
/************************************************************************/
// bootstrapping
window.___OriginalHTMLFormElement___ = null;
window.onload = function (event) {
var form = document.getElementsByTagName ('form')[0];
if (form) {
___OriginalHTMLFormElement___ = form.cloneNode (true);
var first = initLinkage.call (form, 'input.data1', 'input.data2', 'input.data3', 'input.data4');
if (first) {
dispatchChangeEvent.call (first);
}
}
};
////////////////////////////////////////////////////////////////////////
// extends EventTarget
function dispatchChangeEvent () {
if (this.onchange) return this.onchange ();
}
// extends HTMLElement
function getSingleElement (elementName) {
var nodes = this.getElementsByTagName (elementName);
return function (/*class-or-number-list*/) {
var i = 0;
var I = arguments.length;
while (i < I) {
var name = arguments[i++];
switch (typeof name) {
case 'number' :
return nodes[name];
case 'string' :
var j = 0;
var J = nodes.length;
while (j < J) {
var node = nodes[j++];
var expression = new RegExp (' +' + name + ' +', '');
if (expression.test (' ' + node.className + ' ')) {
return node;
}
}
default :
break;
}
}
return null;
};
}
// extends HTMLFormElement
function initLinkage (/*name-list*/) {
var i = 0;
var I = arguments.length;
while (i < I) {
var name = arguments[i++];
var node = this.elements[name];
var nextName = arguments[i];
if (node && nextName) {
node.onchange = function (event) {
var name = arguments.callee.nextName;
synchronize.call (this, this.form.elements[name]);
};
node.onchange.nextName = nextName;
}
node = nextName = null;
}
return this.elements[ arguments[0] ];
}
// extends HTMLSelectElement
function synchronize (other /*htmlSelectElement*/) {
other = recoverNode.call (other);
var label = this.options[ this.selectedIndex ].text;
var optgroups = other.getElementsByTagName ('optgroup');
var optgroup = enableGroup.call (optgroups, label)[0];
var option;
if (optgroup) {
option = getSingleElement.call (optgroup, 'option')('selected', 0);
}
other.selectedIndex = option ? option.index : 0;
other.selectedIndex = option ? option.index : 0; // for fucking IE!
dispatchChangeEvent.call (other);
}
// extends HTMLSelectElement
function recoverNode () {
var clone, form = ___OriginalHTMLFormElement___;
try {
clone = form.elements[ this.name ].cloneNode (true);
clone.onchange = this.onchange;
} catch (error) { // Opera 9.0
try {
var collection = form.elements;
for (var i = 0, I = collection.length; i < I; i++) {
if (collection[i].name == this.name) {
clone = collection[i].cloneNode (true); break;
}
}
clone.onchange = this.onchange;
} catch (error) { // Safari 2.0
document.body.appendChild (form);
clone = form.elements[ this.name ].cloneNode (true);
document.body.removeChild (form);
clone.onchange = this.onchange;
}
}
this.parentNode.replaceChild (clone, this);
return clone;
}
// interface HTMLOptGroupsCollection
function enableGroup (label) {
var result = [ ];
var I = this.length;
var i = 0;
while (i < I) {
var optgroup = this[i++];
if (optgroup.label == label) {
result.push (optgroup);
} else {
optgroup.parentNode.removeChild (optgroup); i--, I--;
}
}
return result;
};
/************************************************************************/
} )();
</script>
</head>
<body>
<form action="#">
<p>
<select name="input.data1">
<option>-</option>
<option>SHARP</option>
<option selected="selected">NEC</option>
<option>FUJITSU</option>
</select>
<select name="input.data2">
<option>-</option>
<optgroup label="SHARP">
<option>MZ-80K</option>
<option class="selected">MZ-700</option>
<option>MZ-2500</option>
</optgroup>
<optgroup label="NEC">
<option>PC-6001</option>
<option>PC-8001</option>
<option class="selected">PC-9801</option>
<option>PC-9821</option>
</optgroup>
<optgroup label="FUJITSU">
<option>FM-8</option>
<option>FM-7</option>
<option>FM-11</option>
<option>FM-77AV</option>
</optgroup>
</select>
<select name="input.data3">
<option>-</option>
<optgroup label="MZ-700">
<option>あいうえお</option>
<option>かきくけこ</option>
</optgroup>
<optgroup label="PC-9801">
<option>さしすせそ</option>
<option class="selected">たちつてと</option>
</optgroup>
<optgroup label="FM-77AV">
<option>なにぬねの</option>
</optgroup>
</select>
<select name="input.data4">
<option>-</option>
<optgroup label="たちつてと">
<option>はひふへほ</option>
<option>まみむめも</option>
</optgroup>
<optgroup label="なにぬねの">
<option>やゆよ</option>
<option>らりるれろ</option>
<option>わをん</option>
</optgroup>
</select>
</p>
</form>
</body>
</html>var LinkageData = {
'input.data1' : {
'Maker' : [[ 'SHARP' , '', false ], // text, value, selected
[ 'NEC' , '', true ],
[ 'FUJITSU', '', false ]]
},
'input.data2' : {
'SHARP' : [[ 'MZ-80K' , '', false ],
[ 'MZ-700' , '', true ],
[ 'MZ-2500', '', false ]],
'NEC' : [[ 'PC-6001', '', false ],
[ 'PC-8001', '', false ],
[ 'PC-9801', '', true ],
[ 'PC-9821', '', false ]],
'FUJITSU' : [[ 'FM-8' , '', false ],
[ 'FM-7' , '', false ],
[ 'FM-11' , '', false ],
[ 'FM-77AV', '', false ]]
}
}// extends HTMLElement
function getSingleElement (elementName) {
var expression = 'descendant::*[ local-name() = "' + elementName + '" and namespace-uri() = "http://www.w3.org/1999/xhtml"]';
var context = this;
var resolver = this.ownerDocument.createNSResolver (this);
var type = XPathResult.FIRST_ORDERED_NODE_TYPE;
return function (/*xpath-predicate-list*/) {
var I = arguments.length;
var i = 0;
while (i < I) {
var expr = expression.concat ('[', arguments[i++], ']');
var node = context.ownerDocument.evaluate (expr, context, resolver, type, null).singleNodeValue;
if (node) return node;
}
return null;
};
}
// extends HTMLSelectElement
function synchronize (other /*htmlSelectElement*/) {
if (this.isSupported ('HTML', '2.0')) {
var label = this.options[ this.selectedIndex ].text;
var optgroups = other.getElementsByTagNameNS ('http://www.w3.org/1999/xhtml', 'optgroup');
var optgroup = enableGroup.call (optgroups, label)[0];
var option;
if (optgroup) {
option = getSingleElement.call (optgroup, 'option')(
'contains( " selected ", concat( " ", normalize-space( @class), " "))',
'position() = 1'
);
}
other.selectedIndex = option ? option.index : 0;
}
dispatchChangeEvent.call (other);
}
// interface HTMLOptGroupsCollection
function enableGroup (label) {
var result = [ ];
Array.forEach (this, function (optgroup) {
if (optgroup.getAttribute ('label') == label) {
optgroup.removeAttribute ('disabled');
result.push (optgroup);
} else {
optgroup.setAttribute ('disabled', 'disabled');
}
} );
return result;
}