RichFaces, modalPanel and developer (that’s me in this case) stupidity
Ever since I started using RichFaces as my core JSF web component framework (that is, almost a year by now) I faced a recurring issue.
There’s a typical patter in applications where there’s some sort of data whose details are shown inside a rich:modalPanel. Usually this comes from a list of entries, where some command (Link or Button, for instance):
- fires an actionListener (receiving some parameters to identify the selected entry, load it from a database, for instance, and populate a bean that will feed the said modalPanel);
- contains an <rich:componentControl … operation=”show”> for that modalPanel.
Pretty simple and works great except for a rathar obnoxious problem: the componentControl with event=”onclick” displays the modalPanel immediately, but it’s data is not yet available. Depending on how loaded your system is or your client latency, there can be a relatively long time before any correct data might be shown. Anything beyond a a few hundred milliseconds can get the user very confused (think of old data showing up first then being ‘magically’ replaced with other data, or an empty form suddendly being populated).
What happend actually makes perfect sense, that is: your modalPanel got displayed, but your data is not yet available. It gets displayed when ready.
This always bugged me and I though of many arcane solutions for this, with lots of components with rendered conditions and reRender attributes. Never a decent solutioin.
Turns out, and I can’t think how this never ocurred me, that the problem wasn’t really with the processing, but with WHEN I was displaying the modalPanel. Solution:
- Instead of having rich:componentControl firing an operation with event=”onclick” (instant display of modalPanel, delayed display of correct data), it should fire with event=”oncomplete”, thus displaying the modalPanel when the data is already available (assuming the actionListener populates the data).
- This fixes the problem of data replacement, but not of delay for itself (if your actionListener takes a long time to process, for instance). Simple fix: have a componentControl display some sort of “wait, loading” message with event=”onclick” and another, with event=”oncomplete” display your data and get rid of your message.
I’m really glad I sorted this out.