Let’s continue with the same
Contact domain model class that we used in Chapter 9. We wish to create a form that allows the user to update the name and email address for a
Contact. Smalltalkers are generally very careful to separate presentation from the core of the data model, so we will create a component that will hold the user interface code to allow the user to edit the underlying
WAComponent subclass: #ContactView
Notice that we’ve specified a
contact instance variable; this will be used to hold a reference to the instance of the
Contact class that we want to edit. Now we create the accessors for the
contact instance variable.
Look carefully at the
contact method below. Before returning the value of the
contact instance variable, it checks that it has been set. If it hasn’t been set, the code in the block is executed which assigns a sensible value to the variable. This lazy initialisation is a common idiom in Smalltalk code. At the moment we want to test this component as a stand alone component, so the accessor method will lazily load one of the contacts for us.
^ contact ifNil: [ contact := Contact contacts first ]
contact := aContact
Next, we introduce our first new canvas message: the message
form. This method returns an instance of
WAFormTag. The only message in
WAFormTag of interest to us right now is
with: which, as we’ve seen before, takes an argument and renders that argument between the open and close XHTML tags (i.e. the
</form> tags in this case). Controls such as input fields, buttons, popups, list boxes, and so on must all be placed inside a
Forgetting to add the form element is a common mistake. Controls such as input fields, buttons, popups, list boxes etc., must all be placed inside a
form tag. If not, they may not be rendered, or they may be rendered but then ignored by the browser.
Our form will have three elements: two text boxes, one each for the name and the email address; and a button for the user to submit their changes.
Let’s look first at the text fields for the name and e-mail address inputs. These fields are created by the canvas’
textInput message which returns a
WATextInputTag. For each brush we use two methods
callback: . The
value: method determines what should be put into this field when it is displayed to the user; here we use the accessor methods on the
Contact instance to give these values. The
callback: method takes a block that has a single argument. When the user submits the form, the block will have the new contents of the field passed to it using this argument; here we use this to update the
Contact instance (via its accessor methods).
Finally we would like our component to have a Save button. We create a button with the canvas
submitButton method, which answers a
WASubmitButtonTag. We assign a callback so that when the user presses this button the message
save is sent.
Here’s the rendering method which creates two text inputs and a submit button:
html form: [
html text: 'Name: '.
callback: [ :value | self contact name: value ];
value: self contact name.
html text: 'Email address: '.
callback: [ :value | self contact emailAddress: value ];
value: self contact emailAddress.
callback: [ self save ];
"For now let's just display the contact information"
self inform: self contact name , '--' , self contact emailAddress
In Seaside 3.0, the brushes
textInput you can also use the message
with: interchangeably. They both define the contents of the button of text input field.
When the user’s browser submits this form, first all the input callbacks are processed, then the (single) submit button callback will be processed. The order is important because the input callbacks set the corresponding field in the
Contact instance. The
save method expects those fields to be set before it is invoked.
You should remember that Seaside processes all input field callbacks before the submit button callback.
Register this component as a new application called “contact”, see Section 2.4.5 for details. Point your web browser to http://localhost:8080/contact and you should see the form as shown in Figure 75. Try entering values and submitting the form.