[Seaside] Web Calendar for Seaside
Avi Bryant
seaside@lists.squeakfoundation.org
Sat, 23 Nov 2002 14:02:14 -0800 (PST)
On Sat, 23 Nov 2002 tblanchard@mac.com wrote:
> OK - lets start with creating an application. The config utility has a
> page, which lets me add an application - I name it and it presents a
> pair of popup menus. Based on this - I am guessing that there is only
> one class that is the application - and that this class is configured
> with a default page (the first popup menu) and you can select a
> particular type of session type (the second popup menu). The menus are
> populated as subclasses of WAComponent for the default page and
> subclasses of WASession for the session class selector.
Correct on all counts.
> So all I have to do is write a WAComponent for the first page of my
> app, set it as the entry point in config - then use WASession or a
> subclass of that for the session.
Also correct.
> I think I get that. I'm not quite clear on how to navigate to a new
> page from there though.
You navigate to a new page by creating an instance of a WAComponent
subclass and passing it into the #call: method. So, for example, let's
say you're writing a simple guestbook - it has a default page which lists
the guests, and a link to a page to add a new guest. The first thing you
would do is write the #renderOn: method of the GuestList; somewhere in
there you would render the "Add Guest" link, which you would attach to a
callback that called, say, the #addGuest method on GuestList. So:
GuestList>>renderOn: html
"render the guest list"
...
"render the Add Guest link"
html anchorWithAction: [self addGuest] text: 'Add Guest'.
Ok, now when that link is clicked, #addGuest will be called. That's where
you need to navigate to the AddGuest page. So:
GuestList>>addGuest
self call: (AddGuest new)
Now, that answers your question, sort of. But let's keep going, and look
at AddGuest. We'll give it an instance variable "guest", and
initialize it to a new Guest object.
AddGuest>>initialize
guest := Guest new
The AddGuest page is going to render a form that fills in the fields of
Guest, and it's also going to have a "Save" submit button.
AddGuest>>renderOn: html
html form: [
html textInputWithValue: guest name callback: [:n | guest name: n].
.....
html submitButtonWithAction: [self save] text: 'Save'.
]
Now, here's the interesting part: what happens in #save? In traditional
web app terms, we want to navigate back to the GuestList. So, we could
have something like this:
AddGuest>>save
... do something to save the Guest object ..
self call: (GuestList new)
But in Seaside, every "call" to a page can be "answered" - bringing us
back to the point it was called from. And in fact, it can pass a value
as its answer, which will be returned from the call; in this case, let's
pass the guest object we just created.
AddGuest>>save
self answer: guest
Since AddGuest was called from GuestList, by calling #answer: we're
returning back to the GuestList. But in fact, we're returning back to the
#addGuest method, and we're returning it a Guest object. So in fact
#addGuest should look like this:
GuestList>>addGuest
|newGuest|
newGuest := self call: (AddGuest new).
guests add: newGuest
Did that all make sense?
Avi