Search code examples
smalltalkseaside

Updating Reef parts on the fly


I'm starting to dig into Reef and I'm stumbling upon something I really don't know how to solve...

I have a RETextField and a REButton, and I want the text field's contents to get updated when the button is pressed, so here's what I'm trying:

initializeContents
    self
        add:
            ((RETextField new)
                id: 'myTextField';
                on: #textFieldContents of: self).
    self
        add:
            ((REButton new)
                label: 'Try me!';
                callback: [ 
                    self triggerThenDo: [
                        textFieldContents := textFieldContents , ' and something else']).

This doesn't work, as I should tell the text field to get updated, so I tried:

initializeContents
    self
        add:
            ((RETextField new)
                id: 'myTextField';
                on: #textFieldContents of: self).
    self
        add:
            ((REButton new)
                label: 'Try me!';
                callback: [ 
                    self triggerThenDo: [
                        textFieldContents := textFieldContents , ' and something else'.
                        (self canvas jQuery: '#myTextField') 
                            load html: 
                               [ :h | h text: textFieldContents ] ] ])

But it didn't work either... also tried self canvas jQuery ajax script: etc. without luck.

I'm guessing Reef has its own elegant way of doing this, but I can't find it anywhere... someone? :)


Solution

  • When creating a Reef component, you need to take into account that just form and form widgets can be triggered. In your first example, it should work just if your component is child of REForm. Something like this:

    REForm subclass: #MyForm
        instanceVariableNames: 'textFieldContents'
        classVariableNames: ''
        poolDictionaries: ''
        category: 'ReefSample1-View'.
    
    textFieldContents
        ^textFieldContents
    
    textFieldContents: aString
        textFieldContents := aString
    
    initializeContents 
        self add: (RETextField new 
            on: #textFieldContents of: self).
        self add: (REButton new 
            label: 'Try me!';
            callback: [ self triggerThenDo: [ self inform: self textFieldContents ]]).
    

    ...should work correctly. Also, remember your Reef application needs to be registered using a special mechanism:

    REApplication 
        registerAsApplication: 'name'
        root: MyRootComponent 
    

    This registration adds all library dependences and decorates your application with a dispatcher for managing ajax requests.