9/14/2010

XPages: Pimp your Time Controls Up with DojoAttributes!

Ever wondered how you would use those DojoAttributes? Here is a way on how to customize your time controls, give them another scale, set the displayedValue (the only way i figured out to set a default value when using time/date only controls), and attach client-side javascript events to the dijit control without building it yourself.

Here is how it works:
  1. Make sure, the XPage has set
    dojoParseOnLoad="true" dojoTheme="true"
    either in xp:view tag or in "All Properties" tab
  2. Make sure you have added the following line to your ressources:
    <xp:dojoModule name="dijit.form.TimeTextBox"></xp:dojoModule>
  3. Drag a Date/Time control on your page
  4. Make it "Time" only
  5. Make sure "Use date/time picker pop-up is checked
  6. Mark it and switch to source tab.
  7. Add
    dojoType="dijit.form.TimeTextBox"
    to the xp:dateTimeHelper tag
  8. When you click into the tag xp:dateTimeHelper, you now get a dojo sections in the "All properties" tab (you can type it in by hand too).
  9. Now you can add dojoAttributes like these, and make them computed too:
  • displayedValue: compute a value to be displayed on startup - or just get the value from the document to be displayed
  • onchange: execute some client-side java script
  • constraints: define the properties of this dijit control to show e.g. clickable fields every half an hour instead of every 5 minutes.
  • every other property you need. Consult dojo documentation at:
    http://www.dojotoolkit.org/api/dijit/form/TimeTextBox.html
Note: This works for date controls too. A pity you cannot add a slider that way, or customize other controls...

Here is the complete source code for such an XPage:

<?xml version="1.0" encoding="UTF-8"?>
<xp:view xmlns:xp="http://www.ibm.com/xsp/core"
    xmlns:xc="http://www.ibm.com/xsp/custom"
    dojoParseOnLoad="true"
    dojoTheme="true">
    
    <xp:this.resources>
        <xp:dojoModule name="dijit.form.TimeTextBox"></xp:dojoModule>
        <xp:dojoModule name="dijit.form.DateTextBox"></xp:dojoModule>
    </xp:this.resources>
    
    <xp:inputText value="#{documentTask.EndTime}"
        id="endTime1" required="true" style="width:5em"
        styleClass="lotusText" tabindex="5" defaultValue="17:30">
        <xp:this.converter>
            <xp:convertDateTime type="time"
                timeStyle="short">
            </xp:convertDateTime>
        </xp:this.converter>
    
        <xp:dateTimeHelper
            dojoType="dijit.form.TimeTextBox" id="dateTimeHelperEndTime">
            <xp:this.dojoAttributes>
                <xp:dojoAttribute
                    name="displayedValue">
                    <xp:this.value><![CDATA[#{javascript:getComponent('endTime1')?getComponent('endTime1').value:'17:30';}]]></xp:this.value>
                </xp:dojoAttribute>
                <xp:dojoAttribute name="constraints"
                    value="{timePattern: 'HH:mm', clickableIncrement: 'T00:30:00', visibleIncrement: 'T00:30:00',visibleRange: 'T05:00:00'}">
                </xp:dojoAttribute>
            </xp:this.dojoAttributes>
        </xp:dateTimeHelper>
    </xp:inputText>            
</xp:view>

How you get to know you have worked too much (Developing Lotus Domino)

  • You keep hitting F9 in your feed reader and wonder why nothing is happening
... maybe continued soon with other real life experiences.

Getting your sub-categories right

Do you need to get Data from a specific subcategory in x-pages?

Maybe, you want to use categories to get totals easy and precalculated like this:

You have a view with three categories:
Column 1: Category 1 ("Year")
Column 2: Category 2 ("Customer")
Column 3: Category 3 ("Month(s)")
Column 4,5: some totals for each month

You want to get a specific Category 2, and output alls the stats it has in the Category3...

You could be trying to use a the following code:
viewNav = view1.createViewNavFromCategory("Cat1\\Cat2")

But: until now, it returns only the complete first category "Cat1" in the navigator - well need "Cat2"

The help states explicitly:

createViewNavFromCategory(string):
Creates a view navigator for all entries in a view under a specified category. [..]
-->Subcategories can be specified using backslash notation (don't forget to escape the backslashes), for example, "Asia\\Korea" means the subcategory "Korea" under the main category "Asia."
[..]

But - it does not work yet, maybe it will in 8.5.2 (Lotus Notes 8.5 Forum Post).
Soo... until then, you have to use the following code to get to the category you actually want to use:

var viewEnt:NotesViewEntry = viewNav.getFirst();
// skip the categories we dont need
while(viewEnt!=null && !(viewEnt.getColumnValues().size()>1&&viewEnt.getColumnValues()[1]==variableWithMyWantedCategory2Name))
    viewEnt=viewNav.getNextCategory();
//now were there, dive into this category
viewEnt=viewNav.getNextCategory();
// it also seems to have all following categories... so exit the loop, when we arrive on the next higher category
 while (viewEnt != null&&viewEnt.getIndentLevel()>1) {
     //actual code goes here: output totals for use e.g. in a report
    viewEnt=viewNav.getNextCategory();
}

Here is another workaround, kindly provided by Tommy Valand (very appreciated):

While NotesView.createViewNavFromCategory is broken:
  • create a flat lookup view with all the "category keys" in the first column (separated by any non-subcategory marker,e.g. / or |)
  • then use
    NotesView.getAllEntriesByKey( partialCategoryKey, false )
  • The option false will partially match all the "subcategory" entries.