Sometime ago in
QuirksBlog came across
this post which lead to the
this link which provides an elegant solution to dynamic select boxes.
This set my refactoring mind rolling :) and I figured instead of using an existing attribute why not use the name/id of the controlling select-box !! That done my lazy mind decided one was not enough and so I decided my dynamic select script must control multiple select-boxes. The HTML form for such a thing looks somewhat like this
<form name="testForm">
<select name="regionId">
<option value="_select_"> - Select - </option>
<option value="1">England</option>
<option value="2">France</option>
</select>
<select name="businessId">
<option value="_select_"> - Select - </option>
<option regionId="1" value="1">Cards</option>
<option regionId="1" value="2">Loans</option>
<option regionId="2" value="2">Loans</option>
</select>
<select name="productId">
<option value="_select_"> - Select - </option>
<option regionId="1" businessId="1" value="1">GoldCard</option>
<option regionId="1" businessId="2" value="4">HomeLoan</option>
<option regionId="2" businessId="2" value="4">HomeLoan</option>
<option regionId="1" businessId="2" value="2">PersonalLoan</option>
<option regionId="2" businessId="2" value="2">PersonalLoan</option>
</select>
</form>
The javascript for achieving this is below
function addID(tags) {
if ( tags && document.getElementsByTagName ) {
for ( i = 0; i < tags.length; i++ ) {
var elements = document.getElementsByTagName(tags[i]);
for ( j = 0; j < elements.length; j++ ) {
var elementName = elements[j].getAttribute("name");
if ( elementName ) {
elements[j].setAttribute("id", elementName);
}
} // enfor j
} // endfor i
} // endif
}
function gel(eName) {
if ( document.getElementById ) {
return document.getElementById(eName);
}
return null;
}
function addHandler(target, eventName, eventHandler) {
if ( target ) {
if ( target.addEventListener ) {
target.addEventListener(eventName, eventHandler, true);
return true;
} else if ( target.attachEvent ) {
target.attachEvent("on" + eventName, eventHandler);
return true;
}
}
return false;
}
function addChainedSelect(sourceSelect, targetSelects) {
var numTargets = targetSelects.length;
var originalTargets = new Array(numTargets);
for ( i = 0; i < targetSelects.length; i++ ) {
if ( targetSelects[i] && targetSelects[i].cloneNode ) {
originalTargets[i] = targetSelects[i].cloneNode(true);
if ( targetSelects[i].getAttribute("chainedSelect") ) {
var chainedSelects = targetSelects[i].getAttribute("chainedSelect");
chainedSelects += "," + sourceSelect.name;
targetSelects[i].setAttribute("chainedSelect", chainedSelects);
} else {
targetSelects[i].setAttribute("chainedSelect", sourceSelect.name);
}
}
}
addHandler(sourceSelect, "change", function() {
refreshSelect(sourceSelect, targetSelects, originalTargets);
});
}
function refreshSelect(sourceSelect, targetSelects, originalTargets) {
var curValue = sourceSelect.value;
var srcName = sourceSelect.getAttribute("name");
for ( i = 0; i < targetSelects.length; i++ ) {
clearSelect(targetSelects[i]);
var option = originalTargets[i].getElementsByTagName("option");
var regEx = new RegExp(curValue);
for ( j = 0; j < option.length; j++ ) {
if ( /_select_/.test(option[j].value) || regEx.test(option[j].getAttribute(srcName)) ) {
targetSelects[i].appendChild(option[j].cloneNode(true));
}
} // endfor j
if ( targetSelects[i].getAttribute("chainedSelect") ) {
var chainedSelects = targetSelects[i].getAttribute("chainedSelect").split(",");
for ( j = 0; j < chainedSelects.length; j++ ) {
var chainName = chainedSelects[j];
var chainValue = document.getElementById(chainName).value;
var regEx = new RegExp(chainValue);
var option = targetSelects[i].getElementsByTagName("option");
for ( k = 0; k < option.length; k++ ) {
if ( !/_select_/.test(option[k].value) && !regEx.test(option[k].getAttribute(chainName)) ) {
targetSelects[i].removeChild(option[k]);
}
} // endfor k
} // endfor j
} // endif additional chainedSelects
} // endfor i
}
function clearSelect(selectBox) {
if ( selectBox ) {
var option = selectBox.getElementsByTagName("option");
while ( option[0] ) {
selectBox.removeChild(option[0]);
}
}
}
And the onload calls to initate it all :)
window.onload = function() {
addID(["input", "select", "div", "a"]);
if ( document.getElementById ) {
addChainedSelect(gel("regionId"), [gel("businessId"), gel("productId")]);
addChainedSelect(gel("businessId"), [gel("productId")]);
} // endif gEBI
} // end winload
Have tested it out only in Firefox and that too not extensively so watchout for those bugs ;)
No comments:
Post a Comment