[Seaside-dev] WAMiniCalendar rewrite
Paolo Bonzini
bonzini at gnu.org
Sun Feb 24 17:40:46 UTC 2008
The attached changeset reimplements WAMiniCalendar to not use Squeak's
additional date classes (except if one uses the #month and #month:
accessors; for now in GNU Smalltalk they will not be available). In
addition, to make the patch more palatable, it eases localization (one
has to reimplement #monthNames and #weekDays).
I checked that the methods I used, especially #addDays: and
#subtractDays:, are available in VW too.
Paolo
-------------- next part --------------
WAComponent subclass: #WAMiniCalendar
instanceVariableNames: 'monthIndex year date canSelectBlock selectBlock'
classVariableNames: ''
poolDictionaries: ''
category: 'Seaside-Core-Components-Widgets'!
WAMiniCalendar comment: 'WAMiniCalendar renders a monthly calendar. Users can navigate by month, year, or select a year and a month. Users can select a date in the calendar. Set canSelectBlock to control which dates a user can select. Use selectBlock to perform an action when a user selects a date. WAMiniCalendar>>date returns the selected date.
Select "Mini Calendar" tab of the Functional Seaside Test Suite to run an example (http://127.0.0.1:xxxx/seaside/tests/alltests)
Instance Variables:
canSelectBlock <BlockClosure with date argument> return true if date argument should be rendered with a link, ie user can select that date
date <WAValueHolder on a date> Selected date
monthIndex <WAValueHolder on an Integer> Currently displayed month
year <WAValueHolder on an Integer> Currently displayed year
selectBlock <BlockClosure with date argument> called when user selects a date
'!
!WAMiniCalendar class methodsFor: 'testing'!
canBeRoot
^true
!
example
^self new
! !
!WAMiniCalendar methodsFor: 'testing'!
canSelect: aDate
^canSelectBlock value: aDate
! !
!WAMiniCalendar methodsFor: 'accessing'!
canSelectBlock: aBlock
canSelectBlock := aBlock
!
month
^Month month: self monthIndex year: self year
!
month: aMonth
self monthIndex: aMonth monthIndex.
self year: aMonth year.
!
selectBlock: aBlock
selectBlock := aBlock
!
states
^Array with: date with: monthIndex with: year
! !
!WAMiniCalendar methodsFor: 'accessing-delegated'!
date
^date contents
!
date: aDate
date contents: aDate.
monthIndex contents: aDate monthIndex.
year contents: aDate year
!
monthIndex
^monthIndex contents
!
monthIndex: anInteger
monthIndex contents: anInteger
!
year
^year contents
!
year: anIntegerOrString
year contents: ([anIntegerOrString asInteger] on: Error do: [:error | 1900])
! !
!WAMiniCalendar methodsFor: 'initialization'!
initialize
super initialize.
monthIndex := WAValueHolder with: Date today monthIndex.
year := WAValueHolder with: Date today year.
date := WAValueHolder new.
canSelectBlock := [:value | true].
selectBlock := [:value | self answer: value]
! !
!WAMiniCalendar methodsFor: 'localization'!
monthNames
^(1 to: 12) collect: [ :each | Date nameOfMonth: each ]
!
weekDays
^(1 to: 7) collect: [:i | (Date nameOfDay: i) first: 3]
! !
!WAMiniCalendar methodsFor: 'private'!
monthName
^(Date nameOfMonth: self monthIndex)
!
monthHeading
^self monthName , ' ' , self year toString
!
weeksDo: aBlock
| day nextMonth |
day := Date newDay: 1 monthIndex: self monthIndex year: self year.
day := day subtractDays: day dayOfWeek.
nextMonth := (self monthIndex \\ 12) + 1.
[ day monthIndex = nextMonth ] whileFalse: [
aBlock value: day.
day := day addDays: 7 ]
! !
!WAMiniCalendar methodsFor: 'rendering'!
renderCellForDate: aDate on: html
html tableData:
[(aDate monthIndex = self monthIndex and: [ aDate year = self year ])
ifTrue:
[html span
class: (self date = aDate ifTrue: ['calendarArchiveDate']);
with: [(self canSelect: aDate)
ifTrue:
[html anchor
callback: [self select: aDate];
with: aDate dayOfMonth]
ifFalse: [html text: aDate dayOfMonth]]]]
!
renderContentOn: html
html div
class: 'calendar';
with:
[html span
class: 'calendarCaption';
with: [self renderMonthHeadingOn: html].
html table:
[html tableRow
class: 'calendarTitle';
with: [self weekDays do: [:each | html tableData: each]].
self weeksDo: [:week | self renderRowForWeek: week on: html]].
self renderMonthNavigationOn: html.
html
space;
space.
self renderYearNavigationOn: html]
!
renderMonthHeadingOn: html
html form:
[html select
list: (1 to: 12);
on: #monthIndex of: self;
labels: [:index | Date nameOfMonth: index].
html textInput
maxLength: 4;
on: #year of: self.
html submitButton text: 'Refresh']
!
renderMonthNavigationOn: html
| tab |
tab := #(12 1 2 3 4 5 6 7 8 9 10 11 12 1).
html span
class: 'calendarPrevious';
with:
[html anchor
callback: [
self monthIndex = 1
ifTrue: [ self monthIndex: 12; year: self year - 1]
ifFalse: [ self monthIndex: self monthIndex - 1 ]];
with: ((self monthNames at: (tab at: self monthIndex)) first: 3)].
html space.
html span
class: 'calendarNext';
with:
[html anchor
callback: [
self monthIndex = 12
ifTrue: [ self monthIndex: 1; year: self year + 1]
ifFalse: [ self monthIndex: self monthIndex + 1 ]];
with: ((self monthNames at: (tab at: self monthIndex + 2)) first: 3)].
!
renderRowForWeek: initialDay on: html
html
tableRow: [0 to: 6 do: [:each |
self renderCellForDate: (initialDay addDays: each) on: html]]
!
renderYearNavigationOn: html
html span
class: 'calendarPrevious';
with:
[html anchor
callback: [self year: self year - 1];
with: self year - 1].
html space.
html span
class: 'calendarNext';
with:
[html anchor
callback: [self year: self year + 1];
with: self year + 1]
! !
!WAMiniCalendar methodsFor: 'action'!
select: aDate
self date: aDate.
selectBlock value: aDate
! !
More information about the seaside-dev
mailing list