26.2First Example
Let us go over a simple but complete example. We want to develop an application to manage person, address and phone number as shown in Figure 161.
We define a class Address
with four instance variables and their corresponding accessors.
Object subclass: #Address
instanceVariableNames: 'street place plz canton'
classVariableNames: ''
poolDictionaries: ''
category: 'MaAddress'
Address class>>example1
| address |
address := self new.
address plz: 1001.
address street: 'Sesame'.
address place: 'DreamTown'.
address canton: 'Bern'.
^ address
Then we add the descriptions to the Address
class as follows: the street name and the place are described by a string description, the PLZ is a number with a range between 1000 and 9999, and since the canton is one of the predefined canton list (our address is for Switzerland so far), we describe it as a single option description.
Address class>>descriptionStreet
^ MAStringDescription new
accessor: #street;
label: 'Street';
priority: 100;
yourself
Address class>>descriptionPlz
^ MANumberDescription new
accessor: #plz;
label: 'PLZ';
priority: 200;
beRequired;
min: 1000 ;
max: 9999;
yourself
Address class>>descriptionPlace
^ MAStringDescription new
accessor: #place;
label: 'Place';
priority: 300;
yourself
Address class>>descriptionCanton
^ MASingleOptionDescription new
accessor: #canton;
label: 'Canton' ;
priority: 400;
options: #('Bern' 'Solothurn' 'Aargau' 'Zuerich' 'Schwyz' 'Glarus');
beSorted;
beRequired;
yourself
Now we can start manipulating the descriptions. Inspect the description object of the address object:
| address |
address := Address example1.
address description inspect.
Now we can iterate over the descriptions and get the values associated with the descriptions of our address model:
| address |
address := Address example1.
address description do: [ :description |
Transcript
show: description label; show: ':'; tab;
show: (description toString: (address readUsing: description));
cr ]
Executing the second code snippet outputs the following in the Transcript:
Street: Sesame PLZ: 1001 Place: DreamTown Canton: Bern
Creating a Seaside Editor. Now we are ready to create a Seaside component automatically in a similar manner.
WAComponent subclass: #MyContactAddress
instanceVariableNames: 'addressForm'
classVariableNames: ''
poolDictionaries: ''
category: 'MaAddress'
MyContactAddress>>initialize
super initialize.
addressForm := Address example1 asComponent
MyContactAddress>>children
^ Array with: addressForm
The method asComponent
sent to the address object automatically builds a Seaside component for us. The resulting editor is displayed in Figure 162.
To enable validation and add buttons to save and cancel the editing process is a matter of adding a decoration. The message addValidatedForm
decorates the component with the necessary rendering and behavior.
MyContactAddress>>initialize
super initialize.
addressForm := Address example1 asComponent.
addressForm addValidatedForm
As a result we get a complete address editor, as seen in Figure 163.
In summary Magritte is really easy to use with Seaside. You put your descriptions on the class-side according to a naming-convention. You can then ask your model objects for their descriptions by sending the message description
or alternatively you directly ask Magritte to build a Seaside editor for you by sending the message asComponent
.