You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@wicket.apache.org by Martin Makundi <ma...@koodaripalvelut.com> on 2009/11/04 18:53:38 UTC

New behavior: AjaxFormSubmittingChangeListenerBehavior

Hi!

Here is the final solution. The behavior enables ajax FormSubmitting
component without default form processing (i.e., analogous to
IOnChangeListener). I hope I got it right because that's what I need
;)

I created a jira issue
(https://issues.apache.org/jira/browse/WICKET-2562) proposing to
overcome the reflection hacks:

public abstract class AjaxFormSubmittingChangeListenerBehavior extends
    AjaxFormSubmitBehavior {
  private final static Method hiddenFieldGetter;
  static {
    try {
      hiddenFieldGetter = Form.class.getDeclaredMethod("getHiddenFieldId");
      hiddenFieldGetter.setAccessible(true);
    } catch (Exception e) {
      throw new RuntimeException(e);
    }
  }

  /**
   * @see org.apache.wicket.ajax.AbstractDefaultAjaxBehavior#onBind()
   */
  @Override
  protected void onBind() {
    super.onBind();

    if (!(getComponent() instanceof IOnChangeListener))
    {
      throw new WicketRuntimeException("Behavior " + getClass().getName() +
        " can only be added to an instance of a IOnChangeListener");
    }
  }

  /**
   * @param event
   */
  public AjaxFormSubmittingChangeListenerBehavior(String event) {
    super(event);
  }

  /**
   * @see org.apache.wicket.ajax.form.AjaxFormSubmitBehavior#onError(org.apache.wicket.ajax.AjaxRequestTarget)
   */
  @Override
  protected void onError(AjaxRequestTarget target) {
    onSubmit(target);
  }

  /**
   * @see org.apache.wicket.ajax.form.AjaxFormSubmitBehavior#onEvent(org.apache.wicket.ajax.AjaxRequestTarget)
   */
  @Override
  protected void onEvent(AjaxRequestTarget target) {
    org.mortbay.util.MultiMap parameters =
((org.mortbay.jetty.Request) ((WebRequest) getComponent()
        .getRequest()).getHttpServletRequest()).getParameters();
    parameters.put(getHiddenFieldId(getForm()),
getComponent().urlFor(IOnChangeListener.INTERFACE));
    super.onEvent(target);
  }

  /**
   * @param form
   * @return String
   */
  private String getHiddenFieldId(Form<?> form) {
    try {
      Form<?> root = form.getRootForm();
      return (String) hiddenFieldGetter.invoke(root);
    } catch (Exception e) {
      throw new RuntimeException(e);
    }
  }
}

**
Martin

2009/11/4 Martin Makundi <ma...@koodaripalvelut.com>:
> Hi!
>
> The proposed solution does not work with Modal Windows!!
> * http://osdir.com/ml/users-wicket.apache.org/2009-11/msg00076.html
>
> Modal windws have a fake parent form:
>
> <form style="border-width: 0px; margin: 0px; padding: 0px;
> background-color: transparent; position: static;">
>
> .. and ofcourse it does not have a hidden input field...
>
> .. so the solution gets a bit nastier...
>
> .. we must fake the hidden field value into the request ... ?
>
> Is there another less pervasive way to do this? Maybe alter wicket a bit ;) ?
>
> The solution here is implementation specific and probably works with jetty only:
>
>
> public abstract class
> AjaxFormSubmittingChangeListenerDropDownChoice<T> extends
> DropDownChoice<T> {
>  private final static Method hiddenFieldGetter;
>  static {
>    try {
>      hiddenFieldGetter = Form.class.getDeclaredMethod("getHiddenFieldId");
>      hiddenFieldGetter.setAccessible(true);
>    } catch (Exception e) {
>      throw new RuntimeException(e);
>    }
>  }
>
>  /** Initialize */ {
>    add(new AjaxFormSubmitBehavior(JavaScriptConstants.ONCHANGE) {
>
>      @Override
>      protected void onError(AjaxRequestTarget target) {
>        AjaxFormSubmittingChangeListenerDropDownChoice.this.onError(target);
>      }
>
>      @Override
>      protected void onSubmit(AjaxRequestTarget target) {
>        AjaxFormSubmittingChangeListenerDropDownChoice.this.onSubmit(target);
>      }
>
>      /**
>       * @see org.apache.wicket.ajax.form.AjaxFormSubmitBehavior#onEvent(org.apache.wicket.ajax.AjaxRequestTarget)
>       */
>      @Override
>      protected void onEvent(AjaxRequestTarget target) {
>        org.mortbay.util.MultiMap parameters =
> ((org.mortbay.jetty.Request) ((WebRequest)
> getRequest()).getHttpServletRequest()).getParameters();
>        parameters.put(getHiddenFieldId(AjaxFormSubmittingChangeListenerDropDownChoice.this.getForm()),
>            AjaxFormSubmittingChangeListenerDropDownChoice.this.urlFor(IOnChangeListener.INTERFACE));
>        super.onEvent(target);
>      }
>
>      /**
>       * @param form
>       * @return String
>       */
>      private String getHiddenFieldId(Form<?> form) {
>        try {
>          Form<?> root = form.getRootForm();
>          return (String) hiddenFieldGetter.invoke(root);
>        } catch (Exception e) {
>          throw new RuntimeException(e);
>        }
>      }
>
>    });
>  }
> }
>
>
> **
> Martin
>
>> 2009/11/4 Jeremy Thomerson <je...@wickettraining.com>:
>>> The power of this list is amazing - it seems you just had an entire thread
>>> with yourself and answered your own question.  SYNERGY!  :)
>>>
>>> But seriously, did you have any remaining questions on this that we could
>>> assist with?
>>>
>>>
>>> --
>>> Jeremy Thomerson
>>> http://www.wickettraining.com
>>>
>