Click
  1. Click
  2. CLK-365

Invoke listeners after all control values have been bound

    Details

    • Type: Improvement Improvement
    • Status: Closed
    • Priority: Blocker Blocker
    • Resolution: Fixed
    • Affects Version/s: 1.5 M1
    • Fix Version/s: 1.5 M2
    • Component/s: core
    • Labels:
      None

      Description

      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.

        Activity

        Hide
        Bob Schellink added a comment -

        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.

        Show
        Bob Schellink added a comment - 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.
        Hide
        Bob Schellink added a comment -

        Listeners are registered in a ControlRegistry. After the onProcess event is finished, the listeners are triggered.

        Show
        Bob Schellink added a comment - Listeners are registered in a ControlRegistry. After the onProcess event is finished, the listeners are triggered.

          People

          • Assignee:
            Bob Schellink
            Reporter:
            Bob Schellink
          • Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved:

              Development