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

Now the #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: AddressBookWidgetview.png 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: AddressWidgetview.png

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: AddressWidgeteditor.png

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!