WebWidget in question
By Hilaire on Friday 20 February 2015, 20:59 - Permalink
As I am still discovering Aida, I like to continue with the Address Book tutorial and modify it whereas my knowledge related to Aida grows.
One aspect itching me was: How can I shorten the method view, how to extract the code to view and edit an address into an external object?
One answer (is there other?) is to use WebWidget to both
view and edit an address instance. Looking at the WebWidget
class hierarchy, you identify the method
#build responsible to
define its content.
Therefore I want a WebAddress widget, it knows about its model and whether its content is to view or to edit it:
WebWidget subclass: #WebAddress instanceVariableNames: 'address editable' classVariableNames: '' poolDictionaries: '' category: 'Aidaweb-Tutorial'
Its accessors are obviously:
WebAddress>>address: anAddress address := anAddress WebAddress>>editable: aBoolean editable := aBoolean WebAddress>>isEditable ^ editable
To use the widget, I want two instance creators. One to view an address, one to edit it:
WebAddress class>>edit: anAddress ^ self basicNew editable: true; address: anAddress; initialize WebAddress class>>view: anAddress ^ self basicNew editable: false; address: anAddress; initialize
#build method depends on its editable status:
WebAddress>>build self isEditable ifTrue: [ self buildEdit ] ifFalse: [ self buildView ]
Finally the two build methods look like:
WebAddress>>buildEdit self newTable border: 0. self newCell addTextBold: 'Prénom'. self newCell addTextBold: ' : '. self newCell addInputFieldAspect: #firstName for: address. self newRow. self newCell addTextBold: 'Nom'. self newCell addTextBold: ' : '. self newCell addInputFieldAspect: #lastName for: address. WebAddress>>buildView self table class: #webGrid. self newCell addTextBold: 'Prénom'. self newCell addTextBold: ' : '. self newCell addText: address firstName. self newRow. self newCell addTextBold: 'Nom'. self newCell addTextBold: ' : '. self newCell addText: address lastName
It is a bit long, but we have now both a viewer and an editor to use in our application. Comparing to the address class in the tutorial, I shorten to only first name and family name, it is no problem to extent it to match the tutorial address model.
Now let's see the other interesting part, integrating our viewer and editor in the tutorial example views.
First in the AddressBookApp view:
ADemoAddressBookApp>>viewMain | e | e := WebElement new. e addTextH1: 'Address book'. self observee addresses do: [ :each | e add: (WebAddress view: each). e addLinkTo: each text: 'view'] separatedBy: [e addRuler].
See our main changes. We create a view for each address: (WebAddress view: each), then we add it to the main view WebElement: e add: (WebAddress view: each)
This view renders as: When the user presses the 'view' button it jumps to the AddressApp main view, we change the code accordingly to use our address viewer:
ADemoAddressApp>>viewMain | html | html := WebElement new. html add: (WebAddress view: self observee). html addButtonText: #edit. self style pageFrameWith: html title: 'Address'
This view renders as:
We use the same changes in the edit view, this time we use our widget as an editor:
ADemoAddressApp>>viewEdit | html | html := WebElement new. html addTextH1: 'Add/Edit the address'. html add: (WebAddress edit: self observee). html addButtonText: (self view = #add ifTrue: [ 'Add' ] ifFalse: [ 'Save' ]). self style pageFrameWith: html title: 'Add/edit the address'
We remove a big load of code and replace it with our editor: html add: (WebAddress edit: self observee).
This edit view renders as:
The widget implementation for reusable code was straightforward.
One may question why do you want to do that, after all each address already has its own view with the AddressApp. Well with widgets we can compose several together in a view, I guess so.
My next challenge: how to get back validation with widgets?
That's all folks!