Click to See Complete Forum and Search --> : attempting to create generic easy to maintain javascript


Timg
11-07-2003, 02:41 PM
I'm attempting to turn all page specific functions into generic functions contained in a .js file (or 2). So far I've come up with 2 approaches neither of which is very elegant. Both should work eventually, the examples below while functional are just to illustrate the point.

Which approach makes more sense in a maintainability and future ease of coding sense?

1) An XHTML approach


//one .js file contains both functions
//the html calls the functions

function setFieldAttribByValueCondition(formFieldToCheck, conditionsArray, effectFieldArray, effectValueArray, effectedAttribArray){
for(var i = 0; i < conditionsArray.length; i++){
if(formFieldToCheck.value == conditionsArray[i]){
var value = null;
if(effectValueArray[i] != "true" && effectValueArray[i] != "false"){
value = effectValueArray[i];
}
else {
value = eval(effectValueArray[i])
}

var field = eval("document.forms[0]." + effectFieldArray[i]);
switch(effectedAttribArray[i]){
case "disabled":
field.disabled = value;
break;
case "value":
field.value = value;
break;
}
}
}
}


function doEffect(field){
var conditionsArray = new Array();
var effectFieldArray = new Array();
var effectValueArray = new Array();
var effectedAttribArray = new Array();

var children = field.parentNode.getElementsByTagName("condition");

for(var i = 0; i < children.length; i++){
conditionsArray.push(children[i].getAttributeNode("value").value);
effectFieldArray.push(children[i].getAttributeNode("fieldToEffect").value);
effectValueArray.push(children[i].getAttributeNode("effectValue").value);
effectedAttribArray.push(children[i].getAttributeNode("effectedAttrib").value);
}

setFieldAttribByValueCondition(field, conditionsArray, effectFieldArray, effectValueArray, effectedAttribArray);
}



<html>
<form name="foo">
<inputwrapper>
<input type="text" name="a" onchange="doEffect(this);"/>
<condition value="E" effectedAttrib="disabled" effectValue="true" fieldToEffect="b">
<condition value="N" effectedAttrib="disabled" effectValue="false" fieldToEffect="b"/>
<!-- a way to make a condition work upon multiple fields with additional coding
<condition value="N" effectedAttrib="disabled" effectValue="false">
<field name="b"/>
<field name="c"/>
</condition>
-->
</inputwrapper>
<input type="text" name="b" value=""/>
</form>
</html>



2) 2 .js file approach (one generic js, one specific)


//in .js file #1

function setDisabled(field, disabled){
field.disabled = disabled;
}



//in .js file #2

function doEffectForFieldA(field){
var value = field.value;
if(value == "E") setDisabled(document.forms[0].b,true);
if(value == "N") setDisabled(document.forms[0].b,false);

/* for multiples...

if(value == "N"){
setDisabled(document.forms[0].b,false);
setDisabled(document.forms[0].c,false);
}

*/
}



//html

<html>
<form name="foo">
<input type="text" name="a" onchange="doEffectForFieldA(this);"/>
<input type="text" name="b" value=""/>
</form>
</html>


Issues

Technique #1 while potentially very flexible and robust could easily grow unmaintainable with the addition of other event handlers, processes to evaluate, dataconversions, etc.

Technique #2 while very easy to maintain due to it's simplicity, dictates that a new 'do' function must be written for every field that requires even the smallest additional functionality. This allows for code spaghetti where every developer who touches the code adds their personal flavor to the fucntions they write and the project ends up with a lack of standard JS code.

Which approach would you choose given the options? Or perhaps you've got alternate suggestions?