You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@wicket.apache.org by Joseph Pachod <jp...@thomas-daily.de> on 2010/04/23 17:01:11 UTC

is there some Ajax behavior updating only a component internal state/data ?

hi

I just stumbled upon that AjaxFormComponentUpdatingBehavior directly 
updates the backing model, providing the component validates itself.

This was quite unexpected.

Indeed, if I've two RequiredTextFields with one valid and the other not, 
submitting this form won't update the backing model(s). At the same 
time, though, all the user's inputs are properly kept and displayed.

Is it possible to have a similar behavior using Ajax, like just updating 
the component inner data/model ?

The use case for it is a ListView with reuseItems(true) which loses in 
transit state. In more details, it means the user writes something in 
one of the listitem's textfield, then click on "add new item" => I want 
the textfield's state to be known and preserved, whereas the whole form 
shouldn't be submitted yet.

Thanks in advance

best regards
-- 

Joseph Pachod
IT

THOMAS DAILY GmbH
Adlerstraße 19
79098 Freiburg
Deutschland
T  + 49 761 3 85 59 506
F  + 49 761 3 85 59 550
E  joseph.pachod@thomas-daily.de
www.thomas-daily.de

Geschäftsführer/Managing Directors:
Wendy Thomas, Susanne Larbig
Handelsregister Freiburg i.Br., HRB 3947

Registrieren Sie sich unter www.signin.thomas-daily.de für die kostenfreien TD Morning News, eine  Auswahl aktueller Themen des Tages morgens um 9:00 in Ihrer Mailbox.

Hinweis: Der Redaktionsschluss für unsere TD Morning News ist täglich um 8:30 Uhr. Es werden vorrangig Informationen berücksichtigt, die nach 16:00 Uhr des Vortages eingegangen sind. Die Email-Adresse unserer Redaktion lautet redaktion@thomas-daily.de.

To receive the free TD News International - a selection of the day's top issues delivered to your mail box every day - please register at www.signin.thomas-daily.de

Please note: Information received for our TD News International after 4 p.m. will be given priority for publication the following day. The daily editorial deadline is 8:30 a.m. You can reach our editorial staff at redaktion@thomas-daily.de. 


---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@wicket.apache.org
For additional commands, e-mail: users-help@wicket.apache.org


Re: is there some Ajax behavior updating only a component internal state/data ?

Posted by Joseph Pachod <jp...@thomas-daily.de>.
hi Martin

I tried your code but had issues with it (bound to jetty + to instances 
of IOnChangeListener)).

However, it made me look directly into 
AjaxFormComponentUpdatingBehavior.onEvent(..), where I ended keeping 
only formComponent.inputChanged(); .

But then other issues started to rise: first of all how to call 
convertInput() in FormComponent, which is protected. Then, later on, my 
use case requires that I "setInput" on some CheckBoxes, which isn't 
doable neither.

In the end, it feels like Wicket isn't thought for allowing to play 
directly with component's input,  requiring rather to go through models 
only. This is, I guess, a compromise which makes sense overall (the 
risks of breaking the form process could be quite high I assume).

Regarding my needs, it means, AFAIK, that I'll have to use a copy on my 
model's object in my current form, copying it back when the form is 
successfully submitted.

thanks for your help in understanding that :)

cheers
joseph


Martin Makundi wrote:
> Here:
>
> /**
>  * Submits form without validating it.
>  *
>  * @author Martin
>  */
> 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) {
>     HttpServletRequest httpServletRequest = ((WebRequest) getComponent()
>         .getRequest()).getHttpServletRequest();
>
>     Map parameters;
>
>     if (httpServletRequest instanceof MockHttpServletRequest) {
>       parameters = ((MockHttpServletRequest)
> httpServletRequest).getParameterMap();
>     } else {
>       parameters = ((org.mortbay.jetty.Request)
> httpServletRequest).getParameters();
>     }
>
>     parameters.put(getHiddenFieldId(getForm()),
> getComponent().urlFor(IOnChangeListener.INTERFACE));
>
>     final FormComponent<?> formComponent = (FormComponent<?>) getComponent();
>
>     try {
>       if (isUpdateModel()) {
>         formComponent.inputChanged();
>         formComponent.validate();
>
>         if (!formComponent.hasErrorMessage()) {
>           formComponent.valid();
>           formComponent.updateModel();
>         }
>       }
>
>       super.onEvent(target);
>     } catch (RuntimeException e) {
>       Utils.errorLog(AjaxFormSubmittingChangeListenerBehavior.class, e);
>       onError(target);
>     }
>   }
>
>   /**
>    * @return boolean
>    */
>   protected boolean isUpdateModel() {
>     return true;
>   }
>
>   /**
>    * @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);
>     }
>   }
> }
>
> 2010/4/23 Joseph Pachod <jp...@thomas-daily.de>:
>   
>> Igor Vaynberg wrote:
>>     
>>> there is ajaxformsubmitting behavior which will update the entire form
>>>
>>> -igor
>>>
>>>       
>> thanks
>>
>> however, that's not exactly my need, being just recording the user input
>> (not to loose it) without validating. Is there no way around, like a hook
>> from Ajax to act only on some component internal state ?
>>
>> My use case being the following:
>>
>>     
>>> The use case for it is a ListView with reuseItems(true) which loses in
>>> transit state. In more details, it means the user writes something in one
>>> of
>>> the listitem's textfield, then click on "add new item" => I want the
>>> textfield's state to be known and preserved, whereas the whole form
>>> shouldn't be submitted yet.
>>>       
>> which approach would you recommend ?
>>
>> thanks again
>>
>> joseph
>>
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: users-unsubscribe@wicket.apache.org
>> For additional commands, e-mail: users-help@wicket.apache.org
>>
>>
>>     
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@wicket.apache.org
> For additional commands, e-mail: users-help@wicket.apache.org
>
>   


-- 
Joseph Pachod
IT

THOMAS DAILY GmbH
Adlerstraße 19
79098 Freiburg
Deutschland
T  + 49 761 3 85 59 506
F  + 49 761 3 85 59 550
E  joseph.pachod@thomas-daily.de
www.thomas-daily.de

Geschäftsführer/Managing Directors:
Wendy Thomas, Susanne Larbig
Handelsregister Freiburg i.Br., HRB 3947

Registrieren Sie sich unter www.signin.thomas-daily.de für die kostenfreien TD Morning News, eine  Auswahl aktueller Themen des Tages morgens um 9:00 in Ihrer Mailbox.

Hinweis: Der Redaktionsschluss für unsere TD Morning News ist täglich um 8:30 Uhr. Es werden vorrangig Informationen berücksichtigt, die nach 16:00 Uhr des Vortages eingegangen sind. Die Email-Adresse unserer Redaktion lautet redaktion@thomas-daily.de.

To receive the free TD News International - a selection of the day's top issues delivered to your mail box every day - please register at www.signin.thomas-daily.de

Please note: Information received for our TD News International after 4 p.m. will be given priority for publication the following day. The daily editorial deadline is 8:30 a.m. You can reach our editorial staff at redaktion@thomas-daily.de. 


---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@wicket.apache.org
For additional commands, e-mail: users-help@wicket.apache.org


Re: is there some Ajax behavior updating only a component internal state/data ?

Posted by Joseph Pachod <jp...@thomas-daily.de>.
Martin Makundi wrote:
> Here:
> (..)
>   
looks promising, thanks a lot

I'll test it on Monday (week end calling soon and.. urgent stuff to do 
in between)

thanks again :)

++
joseph

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@wicket.apache.org
For additional commands, e-mail: users-help@wicket.apache.org


Re: is there some Ajax behavior updating only a component internal state/data ?

Posted by Martin Makundi <ma...@koodaripalvelut.com>.
Here:

/**
 * Submits form without validating it.
 *
 * @author Martin
 */
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) {
    HttpServletRequest httpServletRequest = ((WebRequest) getComponent()
        .getRequest()).getHttpServletRequest();

    Map parameters;

    if (httpServletRequest instanceof MockHttpServletRequest) {
      parameters = ((MockHttpServletRequest)
httpServletRequest).getParameterMap();
    } else {
      parameters = ((org.mortbay.jetty.Request)
httpServletRequest).getParameters();
    }

    parameters.put(getHiddenFieldId(getForm()),
getComponent().urlFor(IOnChangeListener.INTERFACE));

    final FormComponent<?> formComponent = (FormComponent<?>) getComponent();

    try {
      if (isUpdateModel()) {
        formComponent.inputChanged();
        formComponent.validate();

        if (!formComponent.hasErrorMessage()) {
          formComponent.valid();
          formComponent.updateModel();
        }
      }

      super.onEvent(target);
    } catch (RuntimeException e) {
      Utils.errorLog(AjaxFormSubmittingChangeListenerBehavior.class, e);
      onError(target);
    }
  }

  /**
   * @return boolean
   */
  protected boolean isUpdateModel() {
    return true;
  }

  /**
   * @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);
    }
  }
}

2010/4/23 Joseph Pachod <jp...@thomas-daily.de>:
> Igor Vaynberg wrote:
>>
>> there is ajaxformsubmitting behavior which will update the entire form
>>
>> -igor
>>
>
> thanks
>
> however, that's not exactly my need, being just recording the user input
> (not to loose it) without validating. Is there no way around, like a hook
> from Ajax to act only on some component internal state ?
>
> My use case being the following:
>
>> The use case for it is a ListView with reuseItems(true) which loses in
>> transit state. In more details, it means the user writes something in one
>> of
>> the listitem's textfield, then click on "add new item" => I want the
>> textfield's state to be known and preserved, whereas the whole form
>> shouldn't be submitted yet.
>
> which approach would you recommend ?
>
> thanks again
>
> joseph
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@wicket.apache.org
> For additional commands, e-mail: users-help@wicket.apache.org
>
>

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@wicket.apache.org
For additional commands, e-mail: users-help@wicket.apache.org


Re: is there some Ajax behavior updating only a component internal state/data ?

Posted by Joseph Pachod <jp...@thomas-daily.de>.
Igor Vaynberg wrote:
> there is ajaxformsubmitting behavior which will update the entire form
>
> -igor
>   
thanks

however, that's not exactly my need, being just recording the user input 
(not to loose it) without validating. Is there no way around, like a 
hook from Ajax to act only on some component internal state ?

My use case being the following:

> The use case for it is a ListView with reuseItems(true) which loses in
> transit state. In more details, it means the user writes something in one of
> the listitem's textfield, then click on "add new item" => I want the
> textfield's state to be known and preserved, whereas the whole form
> shouldn't be submitted yet.

which approach would you recommend ?

thanks again

joseph

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@wicket.apache.org
For additional commands, e-mail: users-help@wicket.apache.org


Re: is there some Ajax behavior updating only a component internal state/data ?

Posted by Igor Vaynberg <ig...@gmail.com>.
there is ajaxformsubmitting behavior which will update the entire form

-igor

On Fri, Apr 23, 2010 at 8:01 AM, Joseph Pachod <jp...@thomas-daily.de> wrote:
> hi
>
> I just stumbled upon that AjaxFormComponentUpdatingBehavior directly updates
> the backing model, providing the component validates itself.
>
> This was quite unexpected.
>
> Indeed, if I've two RequiredTextFields with one valid and the other not,
> submitting this form won't update the backing model(s). At the same time,
> though, all the user's inputs are properly kept and displayed.
>
> Is it possible to have a similar behavior using Ajax, like just updating the
> component inner data/model ?
>
> The use case for it is a ListView with reuseItems(true) which loses in
> transit state. In more details, it means the user writes something in one of
> the listitem's textfield, then click on "add new item" => I want the
> textfield's state to be known and preserved, whereas the whole form
> shouldn't be submitted yet.
>
> Thanks in advance
>
> best regards
> --
>
> Joseph Pachod
> IT
>
> THOMAS DAILY GmbH
> Adlerstraße 19
> 79098 Freiburg
> Deutschland
> T  + 49 761 3 85 59 506
> F  + 49 761 3 85 59 550
> E  joseph.pachod@thomas-daily.de
> www.thomas-daily.de
>
> Geschäftsführer/Managing Directors:
> Wendy Thomas, Susanne Larbig
> Handelsregister Freiburg i.Br., HRB 3947
>
> Registrieren Sie sich unter www.signin.thomas-daily.de für die kostenfreien
> TD Morning News, eine  Auswahl aktueller Themen des Tages morgens um 9:00 in
> Ihrer Mailbox.
>
> Hinweis: Der Redaktionsschluss für unsere TD Morning News ist täglich um
> 8:30 Uhr. Es werden vorrangig Informationen berücksichtigt, die nach 16:00
> Uhr des Vortages eingegangen sind. Die Email-Adresse unserer Redaktion
> lautet redaktion@thomas-daily.de.
>
> To receive the free TD News International - a selection of the day's top
> issues delivered to your mail box every day - please register at
> www.signin.thomas-daily.de
>
> Please note: Information received for our TD News International after 4 p.m.
> will be given priority for publication the following day. The daily
> editorial deadline is 8:30 a.m. You can reach our editorial staff at
> redaktion@thomas-daily.de.
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@wicket.apache.org
> For additional commands, e-mail: users-help@wicket.apache.org
>
>

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@wicket.apache.org
For additional commands, e-mail: users-help@wicket.apache.org