Update 15/9/2011
Here is an example of my initial implementation, similar to the corejsf example above, but using a shorthand syntax to avoid the ifs. This only requires the 2 additional lines in front to declare the namespace. This can be done with global ‘register’ functions, but these in turn have namespacing issues and seem overly complex compared to the code below. Note also that this uses Javascript Object literal syntax to declare the functions (the ‘colon operator’ below, which is also used in JSON). This syntax in Javascript is a concise notation for name value pairs.
This implementation needs rolling out across all the other Javascript – this still needs doing.
var uk=uk||{}; uk.co=uk.co||{}; uk.co.salientsoft=uk.co.salientsoft||{};
uk.co.salientsoft.util= {
clearElement: function(elementId) {
var escapedId = ‘#’ + elementId.replace(/:/g, ‘\\3A ‘);
jQuery(escapedId).val(”);
}
};
Original Post
It is important to avoid collisions between Javascript function/variable names used by different objects – it is all too easy for entirely different pieces of code to be used in the same application and result in a name collision.
A good mechanism to avoid this for both functions and data is detailed in Core JavaServer Faces Edition 3, page 399. An excerpt from this page detailing how this is done is shown below.
JavaScript Namespaces
In “The f:ajax Tag” on page 389, we implemented a JavaScript function—showProgress()—that uses Prototype to show and hide a DOM element. That method is fragile, however, because it can be overwritten by another JavaScript method of the same name.
It sounds plausible that someone might implement another JavaScript function named showProgress(), thereby replacing your version of the method with theirs. To prevent that replacement from happening, you could name your function something more unique, such as com.corejsf.showProgress(). With that strategy in mind for protecting our JavaScript method from being overwritten, we implement a simple map that serves as a namespace, and we define functions in that map**:
if (!com) var com = {}
if (!com.corejsf) {
com.corejsf = {
showProgress: function(data) {
var inputId = data.source.id
var progressbarId = inputId.substring(0, inputId.length – “name”.length) + “pole”;
if (data.status == “begin”)
Element.show(progressbarId);
else if (data.status == “success”)
Element.hide(progressbarId);
}
}
}
So now the caller accesses the function through the namespace, like this:
<f:ajax event=”blur” render=”nameError” onevent=”com.corejsf.showProgress”/>
JavaScript namespacing not only prevents others from overwriting your functions, but it also indicates to readers of your code that you are a JavaScript coder of some substance.
NOTE: Besides creating an ad-hoc namespace by putting JavaScript functions in a map, you can also put data in a map. Namespacing data is a consideration when you implement custom components that maintain data on the client. If you have multiple instances of the component, they will overwrite each other’s data. Putting the data in a map, keyed by the client identifier of the component to which the data is associated, is a way to ensure that multiple Ajax-based custom components of the same type that store data on the client, can co-exist in a single page.
** The map is actually an object literal—JavaScript does not have a map data structure—but semantically a JavaScript object literal is similar to a map.