Thursday, June 27, 2013

Dynamic Computed Values in an XPage without Javascript

Yesterday, I was trying to created a Computed Field on an Xpage that is based on the editable values of input fields on the same page.   My application is using managed beans to persist all backend data prior to writing it out to a NotesDocument.   Admittedly, I was a bit tired, but all I could think of how to do this was to use Serverside Javascript or Clientside Javascript.  I am comfortable with either method, but I had this nagging doubt that there must be a better way since I was already using java.

I decided to put in a Stack Overflow and ask what was the best practice for computed values using beans.   Stephan Wissel answered my question and the answer was fairly simple.   I was thinking along the correct lines that there was a better way than javascript.   Stephan said that I need to remove my set method from the bean, and to put my logic in the get method.

Sure enough, this worked just as he said.   I was somehow under the impression that each instance variable of the bean had to have one getter and one setter, like it was a required part of the bean specification.  It turns out that this isn't exactly correct, I commented out the set() method and it automatically turns the bound input to read only.  I never had learned this before so I thought it worthy of sharing.   Of course the nice side benefit of blogging this, is that I am now 10x more likely to remember this.

The logic for a computed field goes in the Get() method.  For some reason I was thinking the opposite.  To make the value dynamic, I put the computed value in a different container than the editable fields, and did a partial refresh of the container in the onChange event of each input field used in the calculation.  I really like the result.   All of this amounted to an additional six lines of java code in a method that I already had.

To create a dynamic field in summary:

  1. Bind directly to the bean using expression language.  If you are using beans, then you are likely already doing this.  I used an 'Edit Box' to store my 'computed field'.
  2. Comment out or remove the set----() method in the bean
  3. Put your business logic in the get----() method of the bean
  4. Put your dynamic field(s) in a different container element
  5. Refresh the container element using partial refresh

1 comment: