Dynamic Web Development with Seaside

Buy PDF Buy Print

15.7Answer

We just saw how one component can call another and that the other component will appear in place of the one calling it. How do we give back control to the caller or return a result? The method answer: performs this task. It takes an object that we want to return as a parameter.

Let’s demonstrate how to use answer:. We will add two buttons to the interface of the ToDoItemView: one for cancelling the edit and one to return the modified item. Note that in one case we use a normal submitButton, and in the other case we use cancelButton.

Pay attention since the cancel button looks exactly the same as a submit button, but it avoids processing the input callbacks of the form that would modify our model. This means we don’t need to copy the model as we did in Section 11.5.

ToDoItemView>>renderContentOn: html
html heading: 'Edit'.
html form: [
html text: 'Title:'; break.
html textInput
value: self model title;
callback: [ :value | self model title: value ].
html break.
html text: 'Due:'; break.
html dateInput
value: self model due;
callback: [ :value | self model due: value ].
html break.
html submitButton
callback: [ self answer: self model ];
text: 'Save'.
html cancelButton
callback: [ self answer: nil ];
text: 'Cancel' ]

Working directly on the model. Now the use of the cancel button does solve the problem in the above example, but generally this approach isn’t sufficient by itself: when a component returns an answer, you often want to do some additional validation on the potentially invalid object before updating your model.

Therefore, we should also modify the method edit: to edit a copy of the item and, depending on the returned value of the editor, we should replace the current item with its modified copy.

ToDoListView>>edit: anItem
| edited |
edited := self call: (ToDoItemView new model: anItem copy).
edited isNil
ifFalse: [ self model replace: anItem with: edited ]

Add the following method to ToDoList:

ToDoList>>replace: aTodoItem with: anotherItem
self items at: (self items indexOf: aTodoItem) put: anotherItem

Magritte Support. Replacing a copied object works well in our example, but does not if there are other references to the object (because you end up with a new object). One of the advanced features of Magritte (that we present in Chapter 26) is that it uses a Memento to support the automatic cancellation of edited objects: in other words, it copies the whole object during the edit operation into an internal data-structure and then edits only this object. As soon as the changes are saved, it walks over the Memento and pushes the changes to the real object.

Copyright © 23 March 2017 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.