Document Action Logs, Including "Limitless" User Comments
Action Logs are something I'm sure we've all added to the bottom of a Domino web form. Here's an example of one I added to a recent Domino-based app I created and then wrapped with Bootstrap.
The log is shown to the user as a three column table(when, who, what) with the latest action first.
My approach to storing this data has always been to use a single multi-value text field. The value stored might look something like this:
24/09/2013 17:08:12^^24 Sep '13^^17:08^^Joe Bloggs/ROCKALL^^Document Created 24/09/2013 17:08:12^^24 Sep '13^^17:08^^System Admin/ROCKALL^^'New Document' email sent to related users 24/09/2013 17:21:57^^24 Sep '13^^17:21^^Jake Howlett/ROCKALL^^Status changed to Published 24/09/2013 17:21:57^^24 Sep '13^^17:21^^System Admin/ROCKALL^^'Document Published' email sent to related users
This field is built up by recurring calls to a LotusScript method called LogAction() in the WQS agent of the document.
The HTML table the user sees is generated in a Computed Value section that uses an @For() loop to create a <tr> for each entry in the log.
There are inherent limitations to this approach:
- Limit of the amount of data the backend field can store.
- Limit of HTML the Computed Value that displays the table on the web can store.
These limitations can be worked round, but for the majority of cases the above solution will suffice.
Adding Comments
The limitations became an issue recently when I was tasked with including user's comments in the Action Log. So that the log would look something like this:
Notice the comment on the 2nd row down!?
By adding comments, the chance of reaching the data limitations has greatly increased, becoming almost inevitable.
To avoid the limitation I chose to add each individual comment in a field of its own.
Each time an action is performed and logged with an accompanying comment a field called ActionComment_X is added, where X is the number stored in a field called ActionCommentCount incremented by 1.
The backend documents start to look like this:
Then, in the ActionLog field we add a reference to this comment field as an extra delimited field on each line. Notice in the values below that the 3rd line down ends in ^^ActionComment_1
24/09/2013 17:08:12^^24 Sep '13^^17:08^^Joe Bloggs/ROCKALL^^Document Created^^ 24/09/2013 17:08:12^^24 Sep '13^^17:08^^System Admin/ROCKALL^^'New Document' email sent to related users^^ 24/09/2013 17:21:57^^24 Sep '13^^17:21^^Jake Howlett/ROCKALL^^Status changed to Published^^ActionComment_1 24/09/2013 17:21:57^^24 Sep '13^^17:21^^System Admin/ROCKALL^^'Document Published' email sent to related users^^
When the HTML table is generated and each line in the ActionLog field is exploded on the delimiter ("^^") we can simply add the value stored in the comment field, like so:
@If(@Word(log[n];6)=""; ""; @GetField(@Word(log[n];6))
All that remains is to markup the comment in a <blockquote> tag and add a sprinkle of CSS to make it look like a quote.
The only remaining issue is that, if people type in huge great long comments, the amount of HTML generated by the Computed Value quickly reaches its limit.
To get round this I added an ellipsis (copying off Gmail a little) to the end of a truncated comment like so:
Clicking on this ellipsis "button" uses Ajax to go fetch the rest of the comment.
It's a solution I'm happy with and I've been sitting on for a while, thinking of sharing. Just don't know what interest there is? If there is some I can build a demo/download.
NSF still has a limit on the total number of unique item names in a database. By default, it's 64KB for the sum total of all item names, so you'd still be limited to ~4000 comments per record (subject to how many "normal" items the app has). You can set the "Allow more fields in database" option in the database properties to bump this limit up to 22,893. It's unlikely that you'd get 23K comments on any record, so while it's still theoretically finite, in practice, it would almost certainly be enough. Keep in mind, however, this limit is based on item names across the entire NSF, not per note. So if you use this approach for 10 different features in the same NSF with different naming conventions for the incremented item names, you're limited to 23K for the sum total, so on average, each would be limited to ~2K, and a single document that contains a disproportionate number of items, that reduces the limit on how many items any future documents of a different type can store. In practice, again, you're rarely going to hit that limit, but it is a finite limit. The closest I've found to a truly limitless storage mechanism in NSF is MIME... which, now that Domino is so Java-centric, turns out to be a perfect container for serialized Java object hierarchies (or even just single objects). If you're interested, take a look at the work Jesse Gallagher did in this area:
http://www.openntf.org/p/mimeDominoDocument%20Data%20Source
That implementation is XPage-specific, but there's no reason you couldn't take the base techniques from it and apply it within a Java agent.
Reply
Note this page's title has the word "Limitless" inside quote marks ;-)
The limits of the Computed Value would be met way, way before the limits of the number of fields allowed.
For the case(s) I've used the above approach in they'll never get close to either limit (touch wood).
Thanks for the MIME idea. I hadn't thought of that as an option. Should work in LotusScript too.
Reply
Show the rest of this thread
Brilliant ! Thanks for having shared
Reply
A) There's no mention of Rich-text as a limitless log. This can be made to look pretty and virtually unlimited, but a PITA sometimes.
B) You can 'archive' blocks of text off the list when you get to some limit, say 10k, either by deleting the last n entries or even removing element by element depending on the date.
C) You can push comments/logs out to separate docs and look them up on the 'host' doc or embed a single-category lookup. Granted loads of overhead, but helps avoid limits and possibility of rep/save conflicts.
Oh, and by the way, the '^^' delimiter can be a bit limiting, ok for @word, but @explode only uses a single character. If you want to avoid the possibility of a typed in char, use an 'alt-key number combination' to use a non-keyboard character.
Reply