Date components

David Shaffer
Shaffer Consulting

Introduction

There are a few date input components included in Seaside. WADateSelector is probably the most usable among them. WAMiniCalendar is nice for presenting a small HTML calendar and can be combined with other components to produce reasonably appealing interfaces.

WADateSelector

As the name implies, WADateSelector is a date input component. As HTML date widgets go, it is no frills but I like it better than most of the fancy Javascript date popups that I've found. Unless you are determined to present the user with a fancy calendar interface, WADateSelector is a good choice for date input. Here's what it looks like:

This component is very simple to use. Create one in your initialize method, display it in your form in renderContentOn: and be sure to return in your children array. Here's the complete source code for an example:

WAComponent subclass: #STDateSelectorExample
	instanceVariableNames: 'selector '
	classVariableNames: ''
	poolDictionaries: ''
	category: 'STSeasideTutorial'

children
	^Array with: selector


submitted
	self inform: 'You chose ' , selector date mmddyyyy , '.'


renderContentOn: html 
	html form: [
		html render: selector.
		html submitButtonWithAction: [self submitted]]


initialize
	super initialize.
	selector _ WADateSelector new
Be sure to implement a class side canBeRoot method (which returns true) so you can make this component a stand-alone application. After you've made this into an application, play with it a little. After choosing a few valid dates, try picking "February 31, 2004". You should get an exception. This component doesn't prohibit the user from selecting an invalid date but there are enough safeguards in place that submitting an invalid date can be caught. WADateSelector provides dateIsValid to check if the submitted date is valid:
submitted
	selector dateIsValid
		ifTrue: [self inform: 'You chose ' , selector date mmddyyyy , '.']
		ifFalse: [self inform: 'You chose an invalid date']
Now select an invalid date. You'll notice the "You chose an invalid date" dialog and after you press "Ok" you'll also notice that the date selector marks the input field is invalid.

As you play with this component a bit you'll notice that the year provided by the drop-down runs from last year to 5 years from now. You can change the beginning and ending of this range by sending startYear: and endYear: respectively.

WAMiniCalendar

As the name implies, this component presents a small textual calendar. Here's what it looks like with some CSS for color etc:

I believe this component was written for use in SmallBlog, the Seaside blog. It is certainly usable in other applications although it might take some work to get it to look like you want. As with WADateSelector, you can simply use this component directly in your other Seaside components. WAMiniCalendar keeps the notion of the current date which it decorates with the CSS class calendarArchiveDate. Styles are also available for the calendar's heading, day of week headings and navigation links. Here's an example which shows styles used in this particular example:
WAComponent subclass: #STMiniCalendarExample
	instanceVariableNames: 'calendar '
	classVariableNames: ''
	poolDictionaries: ''
	category: 'STSeasideTutorial'

children
	^Array with: calendar


renderContentOn: html 
	html render: calendar.

style
	^ '*.calendar {
background-color: tan;
content-width: auto;
float: left;
}

*.calendarCaption {
	font-weight: bold; 
}

*.calendarTitle {
	font-weight: bold;
}

*.calendar td {
	text-align: right;
}'


initialize
	super initialize.
	calendar _ WAMiniCalendar new.
	calendar date: Date today
Notice I float-ed the calendar div so that the background color would be applied only to the actual content of the calendar. Since this is a CSS block component (rather than an in-line span, for example), you will find limited options in terms of placement in your forms. In general I wrap this component in my own div and then float it inside that div. This seems redundant but gets the desired formatting in most browsers. Please, if you have better style ideas, send them to me. I don't use WAMiniCalendar much myself so I don't have much experience with it. Unfortunately I haven't found a way to use CSS to move the navigation links up to the same row as the month name.

To make the dates into anchors, you need to give the mini-calendar a canSelectBlock and a selectBlock. For example:

initialize
	super initialize.
	calendar _ WAMiniCalendar new.
	calendar date: Date today.
	calendar
		canSelectBlock: [:date | date weekday = #Sunday].
	calendar
		selectBlock: [:date | self showDate: date]

showDate: date 
	self inform: 'You selected ' , date mmddyyyy , '.'
This gives us a calendar with links on Sundays.

Something fancier?

As an experiment I tried to combine WAMiniCalendar and WADateSelector together into a single date component. I present it here as another example of using these components, I have no idea how usable it is in larger applications. One thing to keep in mind is that it does not want to be an in-line component so unless you're a CSS whiz, which I certainly am not, you'll probably not have as much control over placement of this component as you might like. Anyway, here is what the component looks like at first:

Upon pressing the "..." button, one is presented with the calendar:

Rather than displaying the source here, you can just download it SelectorWithCalendar.st and the example SelectorWithCalendarExample.st.