PDA

View Full Version : Passing parameters to custom element extensions


Vladdy
02-12-2003, 03:20 PM
When introducing custom functionality to HTML elements we either use existing attributes to pass configuration parameters (like beetle's fValidate (http://www.peterbailey.net/fValidate/)) or invent our own (like my Tooltips (http://www.vladdy.net/webdesign/ToolTips.html)). While this method is ok for small amount of configuration information, it is not that flexible (you need to edit DTD) and becomes combersome when large amount of configuration parameters is needed.

I figured a more convinient way is to use a CSS like string to pass configuration parameters:
<div myextension="parameter1: value1; parameter2-subparameter1: value2.1; parameter2-subparameter2: value2.2"> </div>

Then initialization routine would contain:
if(myExtensionParameters = divElement.getAttribute('myExtension'))
divElement.myExtension = new myExtensionObject(divElement,myExtensionParameters);


Definition of possible parameters and their values can be done using an array of regular expressions:
myExtensionParamDefenitions = new Array();
myExtensionParamDefenitions['choiceparameter'] = /^\s*(value1a|value1b|value1c)\s*$/;
myExtensionParamDefenitions['stringparameter'] = /^\s*(\w+)\s*$/;
myExtensionParamDefenitions['integerparameter'] = /^\s*(\d+)\s*$/;

Constructor for the myExtensionObject would containd a parseParameters function:
function myExtensionObject(divElement,myExtensionParameters)
{ this.params=new Array();
parseParameters(this.params,myExtensionParamDefenitions,myExtensionParameters);
//Verify parameter initialization, if you like
str='';
for(e in this.params) str+= e + ': ' + this.params[e] + '\n';
alert(str);
//Do whatever you have to do...
}


Function parseParameters has the following code:
function parseParameters(object,definitions,parameters)
{ paramEntries = parameters.split(';');
for(var i=0; i<paramEntries.length; i++)
{ paramEntry = paramEntries[i].split(':');
if(paramEntry.length == 2)
{ paramName = paramEntry[0].replace(/^\s*([\w-]+)\s*$/,'$1');
if(definitions[paramName])
{ res = definitions[paramName].exec(paramEntry[1]);
if(res[1])
object[convertCSSName(paramName)] = res[1];
}
}
}
}

Where convertCSSName function converts CSS type name (background-image) to javascript name (backgroundImage)
function convertCSSName(cssName)
{ sn = cssName.split('-');
rs = sn[0];
for(var i=1; i<sn.length; i++)
rs += sn[i].replace(/^(\w)(\w*)$/,function(str,p1,p2,offset,s){return p1.toUpperCase() + p2;})
return rs;
}

As a result you have params array of myExtensionObject object populated with validated entries. Changes and expansion is done by simply editing myExtensionParamDefenitions array.

Enjoy.

PS: The functions are coded more for clarity rather than for brevity - I'm certain there are ways to improve the implementation.

jkd
02-12-2003, 04:15 PM
Why not just do:

<div bla="{hello: 'world', foo: 7}">

And eval() getAttribute('bla')? You are essentially creating your own structure for packing data into attributes, why not use one that is easily parsable in JS?

Even then, I don't think this makes semantic sense at all, but whatever.

Vladdy
02-12-2003, 05:27 PM
First, I ABSOLUTELY HATE eval() :D :D :D
Second, what you suggested is perfect for internal use. However, if I deside to distribute such component, I need to provide an easy way for a user to configure it. CSS-like syntax seems to be a logical choice. For the same reason I have validation of parameters and their values.

beetle
02-13-2003, 03:44 PM
How come eval() is like the whipping-boy of javascript functions? It always seems to get "bad press" when it rises to the surface. Any good reason for this?

I mean, it's not like the practice of converting a string into a code is all that uncommon, such as unserializing objects in PHP.

Although I do avoid it when unecessary, I make no attempts to avoid it when it's the right tool for the job. Quite frankly, I think it's remarkably handy.