Building an XPages Calendar Custom Control

If you read my blog directly on my site
and not through a RSS reader then you may have seen the nifty calendar
that I wrote in BlogSphere. It’s AJAX based and allows the reader to move
backwards and forwards through the different months to see what other days
have blog entries.

A picture named M2

I wanted to recreate something very
similar in XPages and started looking at a few options. The blogsphere
version is a table which makes sense as it really is tabulated data but
after thinking of a few ways to do it in XPages I decided to move to a
pure CSS generated calendar. Each of the little squares in the calendar
is a simple SPAN and the CSS is used to give them a border, float them
to the left so they all line up after each other and then a surrounding
DIV forces them to wrap around.

The header for the calendar is defined
as simply as



<xp:span styleClass="calHeader">S</xp:span>
<xp:span styleClass="calHeader">M</xp:span>
<xp:span styleClass="calHeader">T</xp:span>
<xp:span styleClass="calHeader">W</xp:span>
<xp:span styleClass="calHeader">T</xp:span>
<xp:span styleClass="calHeader">F</xp:span>
<xp:span styleClass="calHeader">S</xp:span>


The next set of spans are the empty
cells at the start of the calendar. Before I create the empty cells for
the calendar I need to figure out how many there will be so I need a bit
of server side javascript.



viewScope.dispCalYear = @Year(@Now());

viewScope.dispCalMonth = @Month(@Now());
viewScope.daysInMonth = new Date(viewScope.dispCalYear, viewScope.dispCalMonth,
0).getDate();
viewScope.firstDayInMonth = new Date(viewScope.dispCalYear,viewScope.dispCalMonth
-1 ,1).getDay();

Here I get the current year and month.
The number of days in the month is calculated by getting day zero of next
month. JavaScript sees the request for day zero of a month as being a request
for the last day of the previous month. It is a great shortcut because
you don’t need to worry about calculating leapyears, the javascript processor
does all that for you. In javascript January is defined as 0 but in @formula
language January is defined as 1. This explains why I don’t need to add
one to the month.

To get the first day in the month I
pass in the 1st of the current month ( hence the -1 on the month variable
) and call the getDay function. This returns a 0 for Sunday, 1 for Monday
and so on. If your doing a European style calendar where Monday is the
first day on the left make sure you adjust the value returned here as required.

The number that we got back for the
first day in the month is also the number of blank entries we need to pad
the calendar with. To do this in XPages we can use a very simple repeat
control. Repeat controls don’t need to be linked to Domino data sources.
In this case I’m setting the repeat’s source as an integer and the repeat
will repeat that many times. Inside the repeat control I just have a blank
span.

<xp:repeat
id="calBlanks" rows="7" value="#{javascript:viewScope.firstDayInMonth}"
var="calblankVar">
<xp:span styleClass="calBlank" />
</xp:repeat>

Being able to do a repeat based on an
integer also makes generating the actual calendar spans very easy also.
We already have the number of days in the month thanks to the zero day
trick explained above.



<xp:repeat id="repeat1"
rows="31" value="#{javascript:viewScope.daysInMonth}"
IndexVar="calIndex" var="calVar">
<xp:text escape="true" id="computedField1" value="#{javascript:calVar
+ 1}">
<xp:this.styleClass><!DATA[#{javascript:if (calIndex != 0){

       if (calIndex + firstDayInMonth  % 7 ==
0){
       return “firstday”;
} else {
       return “”;
} } }>


</xp:this.styleClass>
<xp:this.converter>
<xp:convertNumber type="number" integerOnly="true"
/>
</xp:this.converter>
</xp:text>
</xp:repeat>


Make sure the repeats max is set to
31 ( the default is 30 and you’ll wonder why certain months don’t show
that 31st day if you forget to change the default ). Inside my repeat I
have a computed field set to display the repeats index plus one ( the index
starts at zero ). I am also calculating the style class so that every eight
span ( including the blank spans ) has a special css class assigned to
it that ensures the row moves down to the next next row of the calendar.

We now have a very simple calendar in
XPages. With some extra coding you can add some forward and backwards links
above the calendar that will add or subtract one to the viewScope month/year
variable and then do a partial update of the panel containing the calendar.
Here’s what my final calendar looks like with the extra coding completed.

A picture named M3

As you can see I have also redone my
calendar CSS so that it blends in well with the oneUI scheme.

Advertisements
Tagged with: ,
Posted in None
4 comments on “Building an XPages Calendar Custom Control
  1. Take a bow sir — brilliant!

    Like

  2. Bruce Elgort says:

    Well done Declan. Thank you.

    Like

  3. Mike McGarel says:

    It looks beautiful.

    Like

  4. solomon says:

    The tips that you have offered are great but we really need to work our blogs to daily basis to make sure that they are not dormant

    Like

Comments are closed.

Archives
%d bloggers like this: