Next week I’ll be speaking at BLUG. I’ve got quite a bit of learning that has come out of my presentation which I will be disseminating in due course, including another article in the Dojox Charting Tutorial that will take charts to the next level and help produce a powerful, drillable dashboard. But there are also some bits of learning that I just won’t have the time to include in my presentation, as well as some that I will be skipping over.
When I first started working with XPages there were a number of concepts that, as someone who predominantly worked on the Notes Client, were unfamiliar for me and took some time to get my head around. Expression Language was one of those. But first a bit of an introduction to computing values, because I’m aware from forums and blogs that some people may not yet be confident in using the Source pane. I know that my initial development was focussed on getting to know the basics, computing values using the wizards, and not changing the default options except when necessary.
Literal values appear in the source code within quotes, so “…”. All computed values will show in the source code as “#{….}” or “${….}”.* # means that its computed dynamically, $ means it’s computed on page load. The default is dynamically and that is the option that would be used for repeat controls, elements in a partial refresh etc. I presume that this has greater impact on performance, though I’m yet to build an application where the overhead has been a noticeable issue. If so, there are times when it would be best practice to use on page load, but if you try changing your hash to a dollar, you’ll find there are occasions where the compiler doesn’t allow this, because the content is not available at page load.
The difference between Expression Language and Server-Side Javascript is that within the curly braces, SSJS is prefixed with javascript: whereas EL just has the value. So for computed dynamically the code would be “#{javascript:….}” for SSJS and “#{….}” for EL.
So that covers the syntax, but what is Expression Language? The Domino Designer help does not elucidate, probably because it’s a Java concept. For me, and no doubt other developers who have lived in the sheltered world of Domino and LotusScript, that alone would be enough to give us heart palpitations! But it’s actually not that complicated. Think of it as like dot notation that we see in LotusScript or, if you’ve used it, JSON. Say you’ve defined a datasource for your XPage that’s a dominoDocument linked to a Notes Form, and you’ve used the default name of document1, so you’ve got something like this in the source pane:
<xp:this.data>
<xp:dominoDocument var=”document1″ formName=”Person”></xp:dominoDocument>
</xp:this.data>
And let’s say you have a field called firstName on your Person form. If you want to display a computed field in, for example, a repeat control you can use SSJS and use or use EL and just enter “#{document1.firstName}”.
Now’s take it a step further. Let’s say you also have a field lastName, but you don’t have a field to show the full name. As a beginner in XPages I would have used SSJS, entering <![CDATA[#{javascript:document1.getDocument().getItemValueString(“firstName”) + ” ” + document1.getDocument().getItemValueString(“lastName”)}]]>. This is a bit wordy and, if you’ve got to combine values a lot, will make your fingers ache. You might be tempted to add a fullName field to the form to get around that, but you don’t need to. We can actually combine EL values. All we need to do is “#{document1.firstName} #{document1.lastName}”. By placing a space between the two EL values, we’re adding a literal space into the outputted string. If you don’t want a space between values, don’t add a space.
And you can extend this concept even further. Say you also have a middleName field that may or may not be entered. Consider this output:
<![CDATA[#{document1.firstName}#{javascript:(document1.getItemValueString(“middleName”)==””) ? “” : ” ” + document1.getItemValueString(“middleName”)} #{document1.lastName}]]>
This will give us “Fred Wilfred Bloggs” if there is a middle name or “John Smith” if there is not. (For those not used to it, the javascript is an abbreviated format for an if…else statement, with the value after the question mark used if the if returns true, the value after the colon used if the if return false.)
Armed with this knowledge, you can do all sorts of powerful formulas, avoid using fields, and type less. You can also extend you’re view controls to combine EL and text on the fly and so use the same Notes View to get different outputs, and so minimise the size of your database view indexes. After all, running the above formula to combine first name, middle name and last name should have better performance for returning 20 entries in a view rather than needing to be computed for a view index every time that index is rebuilt.
* Note, if the SSJS or EL includes double quotes, it will be placed within a CDATA element, so <![CDATA[#{….}]]> or <![CDATA[${….}]]>.