Dynamic Web Development with Seaside

11.5Answer to the Caller

There is a version of the answer message which takes an argument. This version, named answer: returns a value to the caller. One common use of this is to return a boolean to indicate if the user canceled or completed the operation. Since we don’t have a cancel button in our ContactView, let’s add one and answer appropriately, see Figure 84.

But before doing that, we will refactor the renderContentOn: method. It’s too long and overdue for refactoring. Using the refactoring capabilities of your favorite browser, extract methods so that it looks like this.

ContactView>>renderContentOn: html
html form: [
self renderNameOn: html.
self renderEmailOn: html.
self renderGenderOn: html.
self renderSendUpdatesOn: html.
self renderDateOn: html.
self renderSaveOn: html ]

Now edit your new renderSaveOn: method to add a cancel button:

ContactView>>renderSaveOn: html
html submitButton on: #cancel of: self. " <-- added "
html submitButton on: #save of: self

Contact edition with a cancel button

Redefine the following methods to cancel and save the editing.

ContactView>>save
self answer: true
ContactView>>cancel
self answer: false

Now we can change the method ContactViewList>>editContact: to use the returned value to avoid showing the final inform: dialog.

ContactListView>>editContact: aContact
| view |
view := ContactView new.
view contact: aContact.
(self call: view)
ifFalse: [ ^ nil ].
self inform: 'Thanks for editing ' , aContact name

If you try using the application as it currently stands, you may get a nasty surprise: if the user changes the name in the form and then presses Cancel, the underlying object will still be updated! So, rather than passing it the object we want to edit, we should instead pass it a copy of the contact to be edited and then, depending on the result passed by the answer:, decide whether to substitute the corresponding contact in the contact list.

ContactListView>>editContact: aContact
| view copy |
view := ContactView new.
copy := aContact copy.
view contact: copy.
(self call: view)
ifTrue: [ Contact removeContact: aContact; addContact: copy ]

When you edit a user now, you’ll notice that the user ends up moved to the end of the list of the users; this is the expected behaviour.

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.