Dynamic Web Development with Seaside

13.2Hotel Reservation: Task vs. Component

To compare when to use a task or a component, let’s build a minimal hotel reservation application using a task and a component with children. Using a task, it is easy to reuse components and build a flow. Here is a small application that illustrates how to do this. We want to ask the user to specify starting and ending reservation dates. We will define a new subclass of WATask with two instance variables startDate and endDate of the selected period.

WATask subclass: #HotelTask
instanceVariableNames: 'startDate endDate'
classVariableNames: ''
poolDictionaries: ''
category: 'Calendars'

We define a method go that will first create a calendar with selectable dates after today, then create a second calendar with selectable days after the one selected during the first interaction, and finally we will display the dates selected as shown in Figure 93.

HotelTask>>go
startDate := self call: (WAMiniCalendar new
canSelectBlock: [ :date | date > Date today ]).
endDate := self call: (WAMiniCalendar new
canSelectBlock: [ :date | startDate isNil or: [ startDate < date ] ]).
self inform: 'from ' , startDate asString , ' to ' ,
endDate asString , ' ' , (endDate - startDate) days asString ,
' days'

A simple reservation based on task

Note that you could add a confirmation step and loop until the user is OK with his reservation.

Now this solution is not satisfying because the user cannot see both calendars while making his selection. Since we can’t render components in our task, it’s not easy to remedy the situation. We could use the message addMessage: aString to add a message to a component but this is still not good enough. This example demonstrates that tasks are about flow and not about presentation.

HotelTask>>go
startDate := self call: (WAMiniCalendar new
canSelectBlock: [ :date | date > Date today ];
addMessage: 'Select your starting date';
yourself).
endDate := self call: (WAMiniCalendar new
canSelectBlock: [ :date | startDate isNil or: [ startDate < date ] ];
addMessage: 'Select your leaving date';
yourself).
self inform: (endDate - startDate) days asString , ' days: from ' ,
startDate asString , ' to ' , endDate asString , ' '

Copyright © 19 March 2024 Stéphane Ducasse, Lukas Renggli, C. David Shaffer, Rick Zaccone
This book is licensed under a Creative Commons Attribution-Noncommercial-Share Alike 3.0 license.

This book is published using Seaside, Magritte and the Pier book publishing engine.