Example of Using WQOs To Gain Control Over Notes
As mentioned yesterday here's an example of the code I use in my WQO agents to render custom HTML on a form:
'Setup output to the rich-text field called "ViewBody" 'Field can be either Rich Text, Text-List or plain old Text Dim viewbody As New HtmlArea("ViewBody") 'Start adding HTML to it 'Open a new table viewbody.add |<table>| 'All the logic and HTML-building code goes here. 'E.g: Loop through a doc collection and call viewbody.add |<tr><td>|+doc.Title(0)+|</td></tr>| 'Close the table viewbody.add |</table>|
It's that easy!
The code needed to do it has been encapsulated in a class called HTMLArea. I normally put this in the declarations section of the "CommonRoutines" script library which I use in all agents in all my databases.
The code for the HTMLArea class is:
Class HtmlArea Private session As NotesSession Private doc As NotesDocument Private rtitem As NotesRichTextItem Private item As NotesItem Sub New(Byval FieldName As String) Set session = New NotesSession Set doc = session.DocumentContext Set item = doc.GetFirstItem(FieldName) If item.type=1 Then 'Rich text Set rtitem = doc.GetFirstItem(FieldName) Dim richStyle As NotesRichTextStyle Set richStyle = session.CreateRichTextStyle richStyle.PassThruHTML = True Call rtitem.AppendStyle(richStyle) End If End Sub Public Sub add(Byval snip As String) If item.Type=1 Then rtitem.AppendText snip Else item.AppendToTextList snip End If End Sub End Class
How cool is that!? We can now just create whatever HTML we like. It's completely under our control!
I promised there'd be a download for you today but that will have to wait a few more days until I polish it off. As usual I've gotten completely carried away with myself and what could have been a simple database is turning in to a fully-fledged application. As soon as I'm happy with it I'll add it to the sandbox.
For now though here's a little teaser — open the demo database and notice there's a single view called Calendar. Open that view and behold the beauty of the non-Notes-like calendar. Finally I have complete control. Muhahaha.
I know what you're thinking — how come I just opened a normal "?OpenView" URL and it looks like that? Well, you see, what you're looking at is the Form called "$$ViewTemplate for Calendar". The view itself isn't on the form and so you never get to see it the way Notes intended. Instead the form has a rich text field on it and the whole thing is built using the WQO agent attached to the form.
Great stuff Jake - I usually use WQO to do similar things (not as elegantly as you though). The calendar things looks really cool.
Great stuff !!
Is there any bytes limitations when putting a lot of characters in a richtext field or a "classic" field ?
Looks great! Curious for the code.
Renaud. I'd assume there's no limit with RT fields, but could be wrong. Wouldn't be the first time.
That said, if you're pumping out >64kb of text using this method it might be time to question the approach used.
Jake
Cool stuff, really like the design.
Are you a fan of Ivete or did someone hack your teaser example?
Renaud> There's a 64kb limit to appending text to a RTF-field aswell. To solve this you will have to add splitted chunks of htmlcode to several RTF-fields (rtf_1, rtf_2 etc.).
If anyone knows how to add more than 64kb in WQOpen please tell :-)
that was a fast reaction, Jake ;-)
Always happens Mark. You offer people a service and there's always one idiot who acts all "clever" trying to hack it with a bit of HTML and spoils it for the rest of us.
HTML now stripped from the title field.
Jake, is there a reason for the date format to be mm/dd/yyyy? ;-)
Yeah, it's in America. Like all great apps though, it's designed to work on replicas across the pond - independent of date format.
Jake, I don't want to spoil all the fun but have you also seen:
{Link}
ps: IE only
I have now Indy. Vince has done a great job, as always.
Why would it spoil the fun? Is your post merely a "Been done before" comment? Nothing is more annoying when you've spent time on something like this for people to point out that somebody else has done the same thing before. As if wishing to subtract from its value somehow. I'm sure you didn't mean it like that though. It's just that - over the years - I've seen quite a bit of it.
The only thing it has in common with Vince's db is that they're both calendars and both run on Domino.
Forget that my DB is a calendar. It's about HTML output from a WQO. It just happens to be a calendar. As a calendar it's fairly useless, whereas Vince's is pretty good. That's not the point though...
Jake
Nicely done Jake! I also like your GUI usability - double click on calendar day. Also have to applaud you for using a class. I thought you sort of eschewed LS classes - perhaps an incorrect impression. Nice basis to build from.
To answer the 64k question, as long as you call "append" consecutively on chunks smaller than 64k (mind your charset - this can make 64k more like 22 k characters), you can append indefinitely.
I stumbled upon a way to handle it a while ago.
{Link}
Also, depending on your source, just nibbling the text doesn't always work out. For example with NotesStream:
{Link}
(Sorry for all the links Jake)
@Jerry, In your linked post you use "[" and "]" to get pass through HTML. It is better to explicitly set the richtext style:
RichTextStyle style=session.createRichTextStyle()
style.setPassThruHTML(RichTextStyle.YES)
richTextField.appendStyle(style);
When appending text it is then best to keep track on how much you are appending. If you breach a certain size then Domino will add in a new paragraph, potentially in a place that will break something. So keep track and append newlines with the new paragraph flag set as appropriate.
Andre Guirard has written some posts on the topic recently. Looks like ND8 expands the paragraph limit quite a bit.
{Link}
{Link}
@Kerr - yeah - state of the art 2003 coding examples. :-)
Thanks for the tip. I like your example very much.
Interesting you'd notice my aversion to classes Jerry. Very observant of you. I guess the only reason is I've never been that confident in using them. I'm not a real programmer as such, so often feel like I don't know what I'm doing when it comes to "real" coding like adding class definitions in LS. Also that I rarely see the need for them in the code I write in agents. This though I think is a perfect example of when a class is the best thing to use.
Interesting too about the restrictions on the amount we can output using these methods. Only slightly concerning to me though. Personally I'd always try and avoid using the technique for purging large amounts of data.
Jake
Jake,
Looking great, and elegantly implemented using a class. I do like to point out one downside of using WQO agents: they don't scale well. I can't remember the exact science of these limits, but I think you may run into trouble if a lot of pages require an agent to be run, and you have a lot of concurrent users.
Not to subtract the value of your demo, just to point out a potential risk. It is great that after all these years you still come up with fresh Domino innovation.
Hey Jake!!!
Great idea, i can think of multiple instances where using WQO in this manner could be useful.
I've always enjoyed this blog and can imagine the work, time, life that goes into maintaining this level of content for very little in exchange.
You have an uncanny ability to imagine and then to articulate those ideas, fantastic!!!
You opened my eyes with AJAX, JSON/XML Address Picker, nicely done for the time.
Thanks Meh
Ferdy. As always it's horses for courses. Although I'm sure most Domino apps rarely come under the intense load of something like digg.com say. Most apps I develop don't even come close and using WQO is acceptable. Codestore's homepage uses one and I've never noticed any issues. Not that I rank myself up there with digg or anything ;o)
Greg. Thanks. You're exactly the kind of person I aim my content at. Sometimes it can feel like I'm preaching to the converted. The regulars here who provide most of the feeedback are often the ones to say "Yeah, I've been doing that for ages" or "Yeah, so-n-so talked about that a while ago". It's easy to think that there's nothing left I can teach people. But then I have to remember that the majority of my readers - who remain silent for the most part - probably don't know about most of the stuff I might assume everybody does. That's why sometimes what I talk about must seem really obvious to a lot of readers but is still (I hope) of use to many others.
Thanks for the positive feedback. Comments like yours are what keep the site going!
Jake
There's always
Jake, while I do consider myself a reasonably experienced Domino developer, at last, these light bulb moments still come up from time to time after reading one of your articles, rough cuts or blog entries. And if I find out, that you talk about doing something exactly like I prefer to do it, it always triggers to thoughts: 1. I can't be all wrong if Jake does it this way. 2. I'd never come this far, if I hadn't been reading Jakes blog for so many years.
While we're at it: Did the word blog already exist, when you started your "e-zine" (a term no longer found by your full text search).
And to make an appropriate closing: Did you notice, how Andre Guirard classifies codestore as a "reference" rather than a blog in his (still quiet new) performance blog? {Link}
Hi Fabian. When I started blogging (first entry here {Link} ) on this site in 2001 I referred to the "... addition of these regular, friendly, 'blog' style messages from myself". The fact that I felt the need to put the word blog in quotes says a lot. Nobody really knew what a blog was back then. Not like they do now anyway.
By using the term e-zine in codestore's title I'm trying to get away from the idea that this site has since turned in to nothing more than a blog. The fact that Andre Guirard has listed me as a reference as opposed to a blog is actually quite reassuring and I'm both glad and flattered that he has.
"I can't be all wrong if Jake does it this way"
That's made my night, reading that!
Jake
Have you seen Michel Van Der Meiren's blog "Using a QueryOpen agent to renger HTML pages" {<a href="http://blog.lotusnotes.be/domino/archive/2007-07-03-web-query-open-agent.html">Link</a>}. His example uses a class to render a web page in much the same manner. Both make for great reading.
Interesting, unfortunately I cannot see the example in the sandbox (yet)
The WQO & HTML text area has just solved a hideous problem I've been struggling with.
Oh dear - I'll be "borrowing" more Jake Code.
Thanks as always Jake