Click Framework  History | Log In     View a printable version of the current page. Get help!  
Issue Details (XML | Word)

Key: CLK-365
Type: Improvement Improvement
Status: Resolved Resolved
Resolution: Fixed
Priority: Blocker Blocker
Assignee: Bob Schellink
Reporter: Bob Schellink
Votes: 0
Watchers: 0
Operations

If you were logged in you would be able to see more operations.
Click

Invoke listeners after all control values have been bound

Created: 25/May/08 02:54 AM   Updated: 27/Jun/08 11:04 PM
Component/s: core
Affects Version/s: 1.5 M1
Fix Version/s: 1.5 M2


 Description  « Hide
When Control listeners are fired, there is no guarantee that all Control values have been bound to the incoming request. The reason for this behavior is that the #onProcess method fires the listener directly.

The problem this creates is that the listener cannot assume a control will have its value bound. For example the following will not work:

public MyPage extends Page {

    public void onInit() {
Select select1 = new Select("select1");
        select1.setListener(this, "onSelect1");
Select select2 = new Select("select2");
        select2.setListener(this, "onSelect2");
        ...
    }

    public boolean onSelect1() {
        // The call below will return null because select2 have
        // not been processed yet
        select2.getSelectedValues();
    }

    public boolean onSelect2() {
        // The call below will return select1 selected values because
        // select1 have been processed
        select1.getSelectedValues();
    }
}

I have been burned by this before and think we should improve this a little.

By delaying the listener invocation until all controls have been processed should solve this issue. In other words instead of invoking the listener from the #onProcess method, we instead register the listener to the Context, and once all Controls have been processed, we invoke all the registered listeners.

 All   Comments   Change History      Sort Order:
Bob Schellink [28/May/08 08:50 PM]
This issue becomes more prominent when using Containers. A common example using BasicForm could be:

public MyPage extends Page {
  public void onInit() {
     BasicForm form = new BasicForm("form");
     form.add(new Submit("submit", this, "onSubmit"));
     form.add(new TextField("field"));
  }
  
  public boolean onSubmit() {
       // fieldValue will be null because the onSubmit callback is made before field is processed
       String fieldValue = form.getFieldValue("field");
       System.out.println(fieldValue);
  }
}

When the onSubmit callback is made, the TextField called "field" has not been processed yet, thus its value will be null.

Have upped the priority of this issue.

Bob Schellink [27/Jun/08 11:04 PM]
Listeners are registered in a ControlRegistry. After the onProcess event is finished, the listeners are triggered.