You may already be aware that you can use Expression Language (EL) to evaluate information on the server into client-side JavaScript code. However, this does not work in a library function. This post explains how modularize your code and still use EL to read server-side information into client-side JavaScript.
Here’s how it usually plays out:
- You realize that you need to access the value of an xp:inputText control in client-side JavaScript and use EL syntax in button code to retrieve that value. It works well.
- You decide that you’re going to be a good developer and modularize your code for reuse, so you move it to a script library.
- The code fails at the point where it tries to evaluate the EL statement.
- <facepalm>
- You update the library function to accept values evaluated with EL on the page to make it work properly.
An Example
Here’s a page with an xp:inputText (inputText1) and an xp:button to display the value.
alert('Value: ' + dojo.byId('#{id:inputText1}').value);
This works because #{id:inputText1} is evaluated on the server and it returns the actual client-side ID for that element and passes it into the client-side javascript code on the button.
When the page is rendered, it generates this function (and then uses dojo to attach it to the button):
function view__id1__id4_clientSide_onclick(thisEvent) { alert('Value: ' + dojo.byId('view:_id1:inputText1').value); }
Notice that there’s a fully-fleshed out ID where I previously had an EL statement.
If I want to use that code more than once, I’d want to move it to a script library function:
function displayFieldValue() { alert('Value: ' + dojo.byId('#{id:inputText1}').value); }
But when I try it, it doesn’t work. Nothing happens in the UI, but there’s an error that I can see in Firebug:
The error says that it couldn’t find the field so I can display the value. This is because EL statements do not evaluate in script library functions. They only evaluate in code that is on the page.
Modularization
There is a middle ground, though. If you have code that you want to re-use, you can still move it to a script library — you just have to evaluate EL statements on the page and pass them into the library function.
In this same example, change the library function as shown:
function displayFieldValue(fieldID) { alert('Value: ' + dojo.byId(fieldID).value); }
Then call it from the button like this:
displayFieldValue('#{id:inputText1}');
And now it works!
