Showtime
My Blackberry Enterprise Server Push Utility for the Lotus Notes Client, allows you to create Jobs for individual Channel, Message, and Browser Content Pushes, as well as allows you to delete Pushed Channel Icons from defined recipient devices.
Contact Information
Blogger, podcaster, writer, and geek Chris Toohey covers topics from application development to the latest must-have-gadgets.
Latest Updates

More on Mailer...
More on Junction Lite...
More on Remote Console...

More on Controller API Utility...
Products & Applications
Time Tracker
The idea is simple. At the start of your day - upon completion of your first task - create an entry highlighting what you did and whether you feel it was an efficient or inefficient use of your time. Based on several requests, you can also select the priority, apply categories, or even align your time against a project.
For Lotus Notes Client v8.0 and above, you can use the Time Tracker Widget to make this process even easier!
Zephyr
My Configuration-based Rich Text Mail Merge and Emailing Utility, Zephyr allows you to create rich, data-driven emails to support automated workflow - all via Microsoft Word Mail Merge-like architecture. Dear <firstname> allows you to personalize each email message not only to the individual recipient, but also to the individual application workflow event!
xCopy
xCopy is a simple configurable xCopy client for the Lotus Notes client. By creating and defining xCopy Profiles, you can batch process your file backup or remote upload jobs. With the addition of the xCopy sidebar widget, you can easily kick-off these jobs, and modify both the xCopy Profiles and xCopy itself.
Community & Resources
Lotus Technical Information & Education Community
The Lotus Technical Information & Education community is comprised of IBM, business partner, and customer subject matter experts who use product wikis, published articles, white papers, community blogs and the latest in social media to build and share high quality technical content.
OpenNTF.org - Open Source Community for Lotus Notes Domino
OpenNTF is devoted to enabling groups of individuals all over the world to collaborate on IBM Lotus Notes/Domino applications and release them as open source.
developerWorks Lotus : Wikis
Share your deployment experiences and best practices in our wikis and help IBM to create scenarios for successful deployments. Contribute to the community by collaborating on shared content and leverage the shared knowledge from that community.
Creating Dynamic Input Custom Controls for IBM XPages with switchFacet ExtLib Controls
09/24/2012 12:51:00 PM by Chris Toohey
The Extension Library xe:switchFacet Control is quickly becoming my favorite go-to tool for Custom Control development work... but I don't think I use them in what might be considered a traditional sense.
Those of you familiar with a JavaScript Switch will immediately understand what the xe:switchFacet Control does. For everyone else (or for those of you looking for a "how a Lotus Notes developer would understand this" explanation), here's the breakdown:
Understanding the xe:switchFacet Control
At a glance, the xe:switchFacet reads like it's nothing more than a computed Subform. So let's get started by taking a look at a typical computed Subform.
For computed Subforms, a traditional Form Design Element uses some @Formula-driven logic to resolve which Subform should load at any given time.
Example Computed Subform for a Lotus Notes Domino Form
This Subform will use the value of the SomeField NotesItem on the Form/NotesDocument, and load the name-matched Subform. For example, if SomeField is "foo", it will load the "foo" Subform.
Where a Subform is external from the Form Design Element, the xe:switchFacet control actually uses the xp:this.facets facility to have really any control you wish as a child node of the given control. It computes which child node should be displayed at any given time based off code-driven logic.
Now let's take a look at a simple xe:switchFacet control:
<xe:switchFacet
id="switchFacet1"
defaultFacet="foo"
selectedFacet="#{currentDocument.SomeField}">
<xp:this.facets>
<xp:div xp:key="foo">This will be foo...</xp:div>
<xp:div xp:key="meh">This will be meh...</xp:div>
</xp:this.facets>
</xe:switchFacet>
This xe:switchFacet uses the selectedFacet property to evaluate which "xp:key"-keyed control it should return based on the currentDocument's SomeField value.
Unlike a Subform, the xe:switchFacet allows you to define a defaultFacet, in the event there is no matching keyed control.
Now that you've seen a basic xe:switchFacet control, let's look at a JavaScript switch function example:
switch (expression) {
case label1:
statements1
[break;]
case label2:
statements2
[break;]
...
case labelN:
statementsN
[break;]
default:
statements_def
[break;]
}
Get the idea? The xe:switchFacet will only return the key-matched child control.
Using the xe:switchFacet Control
I love using xe:switchFacet controls in Custom Controls. The other day, I published example XPage markup using an xp:repeat control to display a custom control for "events". Here's that markup again:
<ul class="events">
<xp:repeat
var="thisEvent">
<xp:this.value><![CDATA[#{javascript:var db = new Array(@DbName()[0], preferences['db_events']);
var result = @DbLookup(db,'pinlookup',key,3);
return result;}]]></xp:this.value>
<xc:tile_event>
<xc:this.configuration>
<xc:configuration
targetID="#{thisEvent}"
type="list">
</xc:configuration>
</xc:this.configuration>
</xc:tile_event>
</xp:repeat>
</ul>
If you look at the xc:tile_event properties, take note of the configuration.type property. This custom control employs an xe:switchFacet control that checks the configuration.type property to load completely different content based on the property value. As mentioned in that article, I could just as well as set the configuration.type property to "minicard", thus changing what was returned at runtime.
Pretty basic, sure... but let's take this to another level. (And finally discuss the main topic of this article...)
Let's take a look at my xe:dynamic_input.xsp custom control:
<?xml version="1.0" encoding="UTF-8"?>
<xp:view
xmlns:xp="http://www.ibm.com/xsp/core"
xmlns:xe="http://www.ibm.com/xsp/coreex">
<xe:switchFacet
id="switchFacet_type"
defaultFacet="inputText"
selectedFacet="#{compositeData.configuration.type}">
<xp:this.facets>
<xp:panel
disableOutputTag="true"
xp:key="inputText">
<xp:this.rendered><![CDATA[#{javascript:return (compositeData.configuration.type == "inputText") ? true : false;}]]></xp:this.rendered>
<xp:inputText
id="${compositeData.configuration.controlID}"
value="#{currentDocument[compositeData.configuration.targetItem]}"
defaultValue="#{compositeData.configuration.defaultValue}"
multipleSeparator="#{compositeData.configuration.multipleSeparator}" />
</xp:panel>
<xp:panel
disableOutputTag="true"
xp:key="inputTextarea">
<xp:this.rendered><![CDATA[#{javascript:return (compositeData.configuration.type == "inputTextarea") ? true : false;}]]></xp:this.rendered>
<xp:inputTextarea
id="${compositeData.configuration.controlID}"
value="#{currentDocument[compositeData.configuration.targetItem]}"
defaultValue="#{compositeData.configuration.defaultValue}"
multipleSeparator="#{compositeData.configuration.multipleSeparator}" />
</xp:panel>
<xp:panel
disableOutputTag="true"
xp:key="inputRichText">
<xp:this.rendered><![CDATA[#{javascript:return (compositeData.configuration.type == "inputRichText") ? true : false;}]]></xp:this.rendered>
<xp:inputRichText
id="${compositeData.configuration.controlID}"
value="#{currentDocument[compositeData.configuration.targetItem]}"
defaultValue="#{compositeData.configuration.defaultValue}"
multipleSeparator="#{compositeData.configuration.multipleSeparator}" />
</xp:panel>
<xp:panel
disableOutputTag="true"
xp:key="comboBox">
<xp:this.rendered><![CDATA[#{javascript:return (compositeData.configuration.type == "comboBox") ? true : false;}]]></xp:this.rendered>
<xp:comboBox
id="${compositeData.configuration.controlID}"
defaultValue="#{compositeData.configuration.defaultValue}"
value="#{currentDocument[compositeData.configuration.targetItem]}">
<xp:selectItems
value="#{compositeData.configuration.selectItems}">
</xp:selectItems>
</xp:comboBox>
</xp:panel>
<xp:panel
disableOutputTag="true"
xp:key="checkBoxGroup">
<xp:this.rendered><![CDATA[#{javascript:return (compositeData.configuration.type == "checkBoxGroup") ? true : false;}]]></xp:this.rendered>
<xp:checkBoxGroup
id="${compositeData.configuration.controlID}"
defaultValue="#{compositeData.configuration.defaultValue}"
value="#{currentDocument[compositeData.configuration.targetItem]}">
<xp:selectItems
value="#{compositeData.configuration.selectItems}">
</xp:selectItems>
</xp:checkBoxGroup>
</xp:panel>
<xp:panel
disableOutputTag="true"
xp:key="radioGroup">
<xp:this.rendered><![CDATA[#{javascript:return (compositeData.configuration.type == "radioGroup") ? true : false;}]]></xp:this.rendered>
<xp:radioGroup
id="${compositeData.configuration.controlID}"
defaultValue="#{compositeData.configuration.defaultValue}"
value="#{currentDocument[compositeData.configuration.targetItem]}">
<xp:selectItems
value="#{compositeData.configuration.selectItems}">
</xp:selectItems>
</xp:radioGroup>
</xp:panel>
</xp:this.facets>
</xe:switchFacet>
</xp:view>
This control allows you to completely control which input-type control is returned to the user at runtime based completely on configuration vs. hard-coding the desired input controls into the XPage.
Want a simple xp:inputText control?
<xc:dynamic_input>
<xc:this.configuration>
<xc:configuration
type="inputText"
targetItem="title">
</xc:configuration>
</xc:this.configuration>
</xc:dynamic_input>
How about Rich Text?
<xc:dynamic_input>
<xc:this.configuration>
<xc:configuration
type="inputRichText"
targetItem="body">
</xc:configuration>
</xc:this.configuration>
</xc:dynamic_input>
What about a RadioGroup with selectItems based on an @DbLookup?!
<xc:dynamic_input>
<xc:this.configuration>
<xc:configuration
targetItem="category"
type="radioGroup"
controlID="category">
<xc:this.selectItems><![CDATA[#{javascript:return @DbColumn(['', ''], 'keywords', 1);}]]></xc:this.selectItems>
</xc:configuration>
</xc:this.configuration>
</xc:dynamic_input>
Using the xe:switchFacet to control exactly what is returned at runtime based on Custom Control properties, I could literally wire every native property for any control, and simply pass values through to the controls based on something like a Resource Bundle.
-- or a "configuration" set of NotesDocuments.
In fact, I have a scenario for a project that I'm working on that required a non-technical user to create "surveys", each "survey" with completely unique fields and potential values. While I'm not saying that this exact technique should replace your standard XPages development of creating xp:inputText controls when you need a simple xp:inputText control, I am saying that the xe:switchFacet gives us options. And options can be an amazing thing.
Online Demo
Want to give it a spin? Check out the online demo for this article here:
xe:switchFacet Custom Controls IBM XPages Demo
Conclusion
It's another code-writing-code article... but hopefully this explains why I'm loving the xe:switchFacet control lately. Aside from the demo, I'm using this control to create single-element custom controls to house any/all of my NotesDocument rendering needs.
Need this repeat to display HTML Unordered ListItems (type="list")? Need it to display larger-scale HTML DIV (type="minicard")? Need it to display the entire document in a stylized read-only context (type="fulldoc")?
And the beauty of this is that I can just as easily add another keyed control to the xe:switchFacet-driven Custom Control and change what is displayed not through source code manipulation of various XPages... but in that Resource Bundle that defines which of my Custom Control's facets should actually display.
So are you using xe:switchFacet controls? If you didn't know about them before this article, how do you think you'll use them in your future XPages development? Comment/Like/Collaborate below!


