HTML-CalendarMonth reviews

cpanratings
 

RSS | Module Info | Add a review of HTML-CalendarMonth

HTML-CalendarMonth (1.18) *****

I had to whip up a calendar function at work. I narrowed the choice of the workhorse calendar module down to a short-list of two modules, HTML::CalendarMonth and HTML::CalendarMonthSimple. The documentation to the latter modules seemed excessively complex for a module that is purported to be a simpler version of the former, so I went with the former, since its documentation was easier to come to grips with.

I am very pleased with this module. I had a bit of trouble getting it to work, since I was using an aging 5.6 ActiveState distribution on Win32. I would have liked to have used HTML::CalendarMonth::Locale to get a non-English language calendar, but AS doesn't/no longer bundles it for their 5.6 distribution. I did manage to download DateTime::Locale which appeared to have all that I needed by way of non-English language widgets, but I was unable to get the two of them to work. It would be nice to have H::CM try to require DT::L dynamically, and pull in what it needs at run-time. As it was, I was able to work around this defficiency by using the 'alias' attribute.

It took me a bit of time to figure out how to use the 'alias' attribute, as the documentation does not explain clearly how to use it. Fortunately, at the end of the documentation is a link to a web page that shows a number of examples about how to use the module. Go read that page, it's crucial to understanding how this all fits together.

The other hassle I had was the HTML::AsSubs doesn't exist on AS 5.6 either. Again, there was a simple work-around available by using HTML::Element to build the content I needed to insert into each day. The main loop to fill out the calendar looks like this (of course it would look better in a monospace font, trying View Source in your browser):

for my $day (1 .. $cal->lastday) {

$cal->item($day)->attr(width => 80);

$cal->item($day)->attr(bgcolor => '#cccccc')

if Day_of_Week($year, $month, $day) == 6;

$cal->item($day)->replace_content($day);

if ($open) {

$cal->item($day)->push_content(

HTML::Element->new('br')

);

$cal->item($day)->push_content(

HTML::Element->new('input',

name => 'd',

value => $day,

type => 'checkbox',

(exists $db_day->{$day} ? (checked => 1) : ()),

)

);

}

if (exists $db_day->{$day}) {

$cal->item($day)->attr(bgcolor => '#ccffcc');

}

}

(where $open is a boolean that indicates if the month is open for edits, or view only, and $db_day is a reference to a hash that indicates that something is active that day). Day_of_Week comes from Date::Calc.

I'm a big fan of chained methods, but I know that not everybody likes them, nevertheless I missed the ability to do stuff like

$cal->cell($cal->maxrow, 0)

->attr(colspan => $cal->last_col+2, align => 'center')

->replace_content($foo);

instead of

$cal->cell($cal->maxrow, 0)->attr(colspan => $cal->last_col+2, align => 'center')

$cal->cell($cal->maxrow, 0)->replace_content($foo);

But I can understand that this would be a lot more effort to support (for instance, cell() would have to broken out into a HTML::CalendarMonth::Cell class to pull that off). But it would be a big win, because sometime the cell specifier gets very complex.

All in all, a very useful module that saved me a considerable amount of time. If you need it, you need it bad.

Well done Matt Sisk, I owe you a beer.