You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@wicket.apache.org by jpswain <jp...@gmail.com> on 2008/11/07 03:31:39 UTC

Wicket - Ajax(Fallback)Button and Form - possible solution to problem

As far as I can tell--and I realize there is a good chance I have missed
something--even with nested forms or buttons set to
setDefaultFormProcessing(false) there is no way to create a functionality
like the Gmail sign-up page with it's "Check Availability" button.  
Basically what I'm trying to do is this:
-------
SIGNUP PAGE:

Username: ________ [button: checkAvailability] [label: "available: yes or
no"]
Pass 1: _________
Pass 2: _________
Email Addr: _________
(etc....)
[submit button: createAccount(submits form, with validators; on success
redirects to new "Yippee, account created!" page)]
--------

The idea here is that pressing the checkAvailability button results in an
Ajax request that responds with the label indicating to the user if this
username is available or not.  This should NOT call the whole form's
onSubmit().  Pressing enter in any text input field here will submit the
whole form (this is how Gmail Sign-up does it).

The problem I encountered is that, unlike with the non-Ajax class Button,
AjaxFallbackButton and AjaxButton do not get anything out of a TextField on
when accessed from the Ajax(Fallback)Button's onSubmit() field in instances
where the whole form is not submitted.  The non-Ajax button does require, it
should be noted, a call to someTextField.updateModel(), which works fine,
but when someTextField.updateModel() is used with the Ajax(Fallback)Button,
then you get a NullPointerException.

I did find a way around this however.  The Button class, which of course
includes the AjaxFallbackButton and AjaxButton classes that directly inherit
from it, has a delegateSubmit() method that can be overridden.  The javadoc
for Wicket's Button class says:

When you add a Wicket Button to a form, and that button is clicked, by
default the button's onSubmit method is called first, and after that the
form's onSubmit method is called. If you want to change this (e.g. you don't
want to call the form's onSubmit method, or you want it called before the
button's onSubmit method), you can override Form.delegateSubmit.

Therefore to take advantage of this I created two classes:
AjaxFallbackButtonCustom and FormCustom.  One good thing is that FormCustom
will handle the all other components the same as before.  AjaxFallbackButton
custom implements the interface SubmitControl which is required so that the
FormCustom knows it can check whether or not it should submit the whole form
when the button is used.

Once you are using both of these, you can perform Ajax requests where you
retrieve text from a TextField or TextArea without submitting a whole form
as you previously could not.

I hope I have explained this somewhat clearly.  I have included a link to a
quickstart demonstrating this with the classes and interface I created. 
With the quickstart I have put in some println's to make it easy to follow
what's being called and when.

Please let me know if I have missed an easier way to do this, or if any of
you committers would be interested in working this funcitonality into the
Wicket codebase.  

QUICKSTART HERE: 
http://cosmiao.com/jps/wicket-quickstart.zip
It is all demonstrated on the Home page.

Thanks,
Jamie
-- 
View this message in context: http://www.nabble.com/Wicket---Ajax%28Fallback%29Button-and-Form---possible-solution-to-problem-tp20373644p20373644.html
Sent from the Wicket - User mailing list archive at Nabble.com.


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


Re: Wicket - Ajax(Fallback)Button and Form - possible solution to problem

Posted by jpswain <jp...@gmail.com>.
Jeremy,

It was getValue() that I was looking for!  I guess I didn't realize the
difference between the Model object and the Component's value.  For some
reason I thought the Model was the necessary glue between the Component and
my Java code.

Thanks for the help man!
Jamie


Jeremy Thomerson-5 wrote:
> 
> Sorry, yes.  Since you are skipping default form processing, it is also
> skipping pushing things onto the models....  So, you have a couple of
> options...
> 
> Option one - get the value directly from the text field, i.e.
> 
> System.*out*.println("USERNAME WAS: " + tfUsername.getValue());
> Option two - don't use setDefaultFormProcessing(false) - only put the
> logic
> for the username check in the checkAvail button, and put all other form
> logic in the main submit button.  Then make sure that the main submit
> button
> is the primary button.  This is probably the better option.
> 
> Hope this helps.
> 
> 
> -- 
> Jeremy Thomerson
> http://www.wickettraining.com
> On Fri, Nov 7, 2008 at 1:00 AM, jpswain <jp...@gmail.com> wrote:
> 
>>
>> Jeremy,
>>
>> Thanks for checking it out!
>> Everything you said is true, except you missed one thing, the button
>> won't
>> get anything out of the field except what was last (if yet) submitted by
>> the
>> entire form to update its model.  So, in this case
>> setDefaultFormProcessing(false) definitely does Not work.  Sorry, it's
>> really my fault for not putting a println in the right spot.
>>
>> To check it out with the "stock" components, then in your
>> checkAvailButton's
>> onSubmit() add this as the last line:
>> System.out.println(">>> username=" + username);
>>
>> You'll see that it's not getting the text out of the field.  Try playing
>> around with it while watching the output there, and it'll make sense what
>> I'm talking about, I hope.
>>
>> Thanks again :),
>> Jamie
>>
>> P.S.
>> I have updated the quickstart, at the same location:
>> http://cosmiao.com/jps/wicket-quickstart.zip
>>
>>
>> Jeremy Thomerson-5 wrote:
>> >
>> > I'm not sure I understand your problem.  I quickly got it working (I
>> > think)
>> > the way you wanted using Wicket's built in classes.  Maybe I
>> misunderstood
>> > you.  Here were the steps I took:
>> >
>> >    1. Took your quickstart and got it in Eclipse
>> >    2. Changed FormCustom to Form
>> >    3. Changed AjaxFallbackButtonCustom to AjaxFallbackButton
>> >    4. added .setDefaultFormProcessing(false) on the checkAvailButton
>> >    5. PROFIT!
>> >
>> > Below, I have pasted the updated HomePage class.  Please let me know if
>> I
>> > didn't understand - but when I run it, it only calls the onSubmit of
>> the
>> > checkAvailButton.  Then, when I click the submitButton, it does both
>> > submit
>> > button and form onSubmit.
>> >
>> >
>> > --
>> > Jeremy Thomerson
>> > http://www.wickettraining.com
>> >
>> >
>> --
>> View this message in context:
>> http://www.nabble.com/Wicket---Ajax%28Fallback%29Button-and-Form---possible-solution-to-problem-tp20373644p20375622.html
>>  Sent from the Wicket - User mailing list archive at Nabble.com.
>>
>>
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: users-unsubscribe@wicket.apache.org
>> For additional commands, e-mail: users-help@wicket.apache.org
>>
>>
> 
> 

-- 
View this message in context: http://www.nabble.com/Wicket---Ajax%28Fallback%29Button-and-Form---possible-solution-to-problem-tp20373644p20388569.html
Sent from the Wicket - User mailing list archive at Nabble.com.


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


Re: Wicket - Ajax(Fallback)Button and Form - possible solution to problem

Posted by Jeremy Thomerson <je...@wickettraining.com>.
Sorry, yes.  Since you are skipping default form processing, it is also
skipping pushing things onto the models....  So, you have a couple of
options...

Option one - get the value directly from the text field, i.e.

System.*out*.println("USERNAME WAS: " + tfUsername.getValue());
Option two - don't use setDefaultFormProcessing(false) - only put the logic
for the username check in the checkAvail button, and put all other form
logic in the main submit button.  Then make sure that the main submit button
is the primary button.  This is probably the better option.

Hope this helps.


-- 
Jeremy Thomerson
http://www.wickettraining.com
On Fri, Nov 7, 2008 at 1:00 AM, jpswain <jp...@gmail.com> wrote:

>
> Jeremy,
>
> Thanks for checking it out!
> Everything you said is true, except you missed one thing, the button won't
> get anything out of the field except what was last (if yet) submitted by
> the
> entire form to update its model.  So, in this case
> setDefaultFormProcessing(false) definitely does Not work.  Sorry, it's
> really my fault for not putting a println in the right spot.
>
> To check it out with the "stock" components, then in your
> checkAvailButton's
> onSubmit() add this as the last line:
> System.out.println(">>> username=" + username);
>
> You'll see that it's not getting the text out of the field.  Try playing
> around with it while watching the output there, and it'll make sense what
> I'm talking about, I hope.
>
> Thanks again :),
> Jamie
>
> P.S.
> I have updated the quickstart, at the same location:
> http://cosmiao.com/jps/wicket-quickstart.zip
>
>
> Jeremy Thomerson-5 wrote:
> >
> > I'm not sure I understand your problem.  I quickly got it working (I
> > think)
> > the way you wanted using Wicket's built in classes.  Maybe I
> misunderstood
> > you.  Here were the steps I took:
> >
> >    1. Took your quickstart and got it in Eclipse
> >    2. Changed FormCustom to Form
> >    3. Changed AjaxFallbackButtonCustom to AjaxFallbackButton
> >    4. added .setDefaultFormProcessing(false) on the checkAvailButton
> >    5. PROFIT!
> >
> > Below, I have pasted the updated HomePage class.  Please let me know if I
> > didn't understand - but when I run it, it only calls the onSubmit of the
> > checkAvailButton.  Then, when I click the submitButton, it does both
> > submit
> > button and form onSubmit.
> >
> >
> > --
> > Jeremy Thomerson
> > http://www.wickettraining.com
> >
> >
> --
> View this message in context:
> http://www.nabble.com/Wicket---Ajax%28Fallback%29Button-and-Form---possible-solution-to-problem-tp20373644p20375622.html
>  Sent from the Wicket - User mailing list archive at Nabble.com.
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@wicket.apache.org
> For additional commands, e-mail: users-help@wicket.apache.org
>
>

Re: Wicket - Ajax(Fallback)Button and Form - possible solution to problem

Posted by jpswain <jp...@gmail.com>.
Jeremy,

Thanks for checking it out!
Everything you said is true, except you missed one thing, the button won't
get anything out of the field except what was last (if yet) submitted by the
entire form to update its model.  So, in this case
setDefaultFormProcessing(false) definitely does Not work.  Sorry, it's
really my fault for not putting a println in the right spot.  

To check it out with the "stock" components, then in your checkAvailButton's
onSubmit() add this as the last line:
System.out.println(">>> username=" + username);

You'll see that it's not getting the text out of the field.  Try playing
around with it while watching the output there, and it'll make sense what
I'm talking about, I hope.  

Thanks again :),
Jamie

P.S.
I have updated the quickstart, at the same location:
http://cosmiao.com/jps/wicket-quickstart.zip


Jeremy Thomerson-5 wrote:
> 
> I'm not sure I understand your problem.  I quickly got it working (I
> think)
> the way you wanted using Wicket's built in classes.  Maybe I misunderstood
> you.  Here were the steps I took:
> 
>    1. Took your quickstart and got it in Eclipse
>    2. Changed FormCustom to Form
>    3. Changed AjaxFallbackButtonCustom to AjaxFallbackButton
>    4. added .setDefaultFormProcessing(false) on the checkAvailButton
>    5. PROFIT!
> 
> Below, I have pasted the updated HomePage class.  Please let me know if I
> didn't understand - but when I run it, it only calls the onSubmit of the
> checkAvailButton.  Then, when I click the submitButton, it does both
> submit
> button and form onSubmit.
> 
> 
> -- 
> Jeremy Thomerson
> http://www.wickettraining.com
> 
> 
-- 
View this message in context: http://www.nabble.com/Wicket---Ajax%28Fallback%29Button-and-Form---possible-solution-to-problem-tp20373644p20375622.html
Sent from the Wicket - User mailing list archive at Nabble.com.


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


Re: Wicket - Ajax(Fallback)Button and Form - possible solution to problem

Posted by Jeremy Thomerson <je...@wickettraining.com>.
I suppose you could do exactly the same - put a div with
style="display:none", and then just add a behavior that changes the display
style with JS on page load.  If the user doesn't have JS enabled, the thing
won't ever show up.

Does that help?

Something like this....  Create an AbstractBehavior, store the component
it's bound to in the bind method, and then do this

    @Override
    public void renderHead(IHeaderResponse response) {
        super.renderHead(response);
        response.renderOnLoadJavascript(component.getMarkupId() +
".style.display = 'block';");
    }

-- 
Jeremy Thomerson
http://www.wickettraining.com

On Thu, Dec 18, 2008 at 11:04 PM, bht <bh...@actrix.gen.nz> wrote:

>
> Jeremy,
>
> jpswain referred to the gmail signup form. The gmail form initially hides
> the "check availability" elements via div with style="display:none". It
> only
> shows them when it detects that AJAX or JavaScript (don't know exactly) is
> available. Would you know how we can implement this with wicket?
> --
> View this message in context:
> http://www.nabble.com/Wicket---Ajax%28Fallback%29Button-and-Form---possible-solution-to-problem-tp20373644p21085893.html
>  Sent from the Wicket - User mailing list archive at Nabble.com.
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@wicket.apache.org
> For additional commands, e-mail: users-help@wicket.apache.org
>
>

Re: Wicket - Ajax(Fallback)Button and Form - possible solution to problem

Posted by bht <bh...@actrix.gen.nz>.
Jeremy,

jpswain referred to the gmail signup form. The gmail form initially hides
the "check availability" elements via div with style="display:none". It only
shows them when it detects that AJAX or JavaScript (don't know exactly) is
available. Would you know how we can implement this with wicket?
-- 
View this message in context: http://www.nabble.com/Wicket---Ajax%28Fallback%29Button-and-Form---possible-solution-to-problem-tp20373644p21085893.html
Sent from the Wicket - User mailing list archive at Nabble.com.


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


Re: Wicket - Ajax(Fallback)Button and Form - possible solution to problem

Posted by Jeremy Thomerson <je...@wickettraining.com>.
I'm not sure I understand your problem.  I quickly got it working (I think)
the way you wanted using Wicket's built in classes.  Maybe I misunderstood
you.  Here were the steps I took:

   1. Took your quickstart and got it in Eclipse
   2. Changed FormCustom to Form
   3. Changed AjaxFallbackButtonCustom to AjaxFallbackButton
   4. added .setDefaultFormProcessing(false) on the checkAvailButton
   5. PROFIT!

Below, I have pasted the updated HomePage class.  Please let me know if I
didn't understand - but when I run it, it only calls the onSubmit of the
checkAvailButton.  Then, when I click the submitButton, it does both submit
button and form onSubmit.


-- 
Jeremy Thomerson
http://www.wickettraining.com

package com.musictramp;
import org.apache.wicket.PageParameters;
import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.ajax.markup.html.form.AjaxFallbackButton;
import org.apache.wicket.markup.html.WebPage;
import org.apache.wicket.markup.html.basic.Label;
import org.apache.wicket.markup.html.form.Form;
import org.apache.wicket.markup.html.form.TextField;
import org.apache.wicket.model.Model;

public class HomePage extends WebPage {
 private static final long serialVersionUID = 1L;
 public HomePage(final PageParameters parameters) {
  Form form = new Form("form"){
   @Override
   protected void onSubmit() {
    System.out.println(">>> form onSubmit() called...");
    // do usual stuff
   }
  };

  form.add(new TextField("username", new
Model("")).setOutputMarkupId(true));
  form.add(new Label("checkAvailLabel", new
Model("")).setOutputMarkupId(true));
  AjaxFallbackButton afb = new AjaxFallbackButton("checkAvailButton", form)
{
   @Override
   protected void onSubmit(AjaxRequestTarget target, Form<?> form) {
    System.out.println(">>> checkAvailButton onSubmit() called...");
    // Let's see if the username is available.
    // Pretend we are checking a DB that tells us the name "wicket" is
taken.
    TextField tfUsername = (TextField) form.get("username");
    String username = "";
    if (tfUsername.getModelObject() != null) {
     username = tfUsername.getModelObject().toString();
    }

    Label checkAvailLabel = (Label) form.get("checkAvailLabel");
    boolean usernameAcceptable = false;
    if (username.equals("")) {
     checkAvailLabel.setDefaultModelObject("Please enter username!");
    } else {
     // Here's where we would check our DB to see if the username is taken
or not:
     if (username.equals("wicket")) {
      checkAvailLabel.setDefaultModelObject(
        "Username taken, please select a different one."
      );
     } else {
      checkAvailLabel.setDefaultModelObject(
        "Yes that username is available!"
      );
      usernameAcceptable = true;
     }
    }
    if (target != null) {
     target.addComponent(checkAvailLabel);
     if (usernameAcceptable) {
      target.focusComponent(form.get("email"));
     } else {
      target.focusComponent(form.get("username"));
     }
    }
   }
  };
  form.add(afb.setDefaultFormProcessing(false));

  form.add(new TextField("email", new Model("")).setOutputMarkupId(true));

  form.add(
   new AjaxFallbackButton("submitButton", form) {
    @Override
    protected void onSubmit(AjaxRequestTarget target, Form<?> form) {
     System.out.println(">>> submitButton onSubmit() called...");
     // do whatever stuff necessary.
    }
   }
  );

  add(form);

 }

}



On Thu, Nov 6, 2008 at 8:31 PM, jpswain <jp...@gmail.com> wrote:

>
> As far as I can tell--and I realize there is a good chance I have missed
> something--even with nested forms or buttons set to
> setDefaultFormProcessing(false) there is no way to create a functionality
> like the Gmail sign-up page with it's "Check Availability" button.
> Basically what I'm trying to do is this:
> -------
> SIGNUP PAGE:
>
> Username: ________ [button: checkAvailability] [label: "available: yes or
> no"]
> Pass 1: _________
> Pass 2: _________
> Email Addr: _________
> (etc....)
> [submit button: createAccount(submits form, with validators; on success
> redirects to new "Yippee, account created!" page)]
> --------
>
> The idea here is that pressing the checkAvailability button results in an
> Ajax request that responds with the label indicating to the user if this
> username is available or not.  This should NOT call the whole form's
> onSubmit().  Pressing enter in any text input field here will submit the
> whole form (this is how Gmail Sign-up does it).
>
> The problem I encountered is that, unlike with the non-Ajax class Button,
> AjaxFallbackButton and AjaxButton do not get anything out of a TextField on
> when accessed from the Ajax(Fallback)Button's onSubmit() field in instances
> where the whole form is not submitted.  The non-Ajax button does require,
> it
> should be noted, a call to someTextField.updateModel(), which works fine,
> but when someTextField.updateModel() is used with the Ajax(Fallback)Button,
> then you get a NullPointerException.
>
> I did find a way around this however.  The Button class, which of course
> includes the AjaxFallbackButton and AjaxButton classes that directly
> inherit
> from it, has a delegateSubmit() method that can be overridden.  The javadoc
> for Wicket's Button class says:
>
> When you add a Wicket Button to a form, and that button is clicked, by
> default the button's onSubmit method is called first, and after that the
> form's onSubmit method is called. If you want to change this (e.g. you
> don't
> want to call the form's onSubmit method, or you want it called before the
> button's onSubmit method), you can override Form.delegateSubmit.
>
> Therefore to take advantage of this I created two classes:
> AjaxFallbackButtonCustom and FormCustom.  One good thing is that FormCustom
> will handle the all other components the same as before.
>  AjaxFallbackButton
> custom implements the interface SubmitControl which is required so that the
> FormCustom knows it can check whether or not it should submit the whole
> form
> when the button is used.
>
> Once you are using both of these, you can perform Ajax requests where you
> retrieve text from a TextField or TextArea without submitting a whole form
> as you previously could not.
>
> I hope I have explained this somewhat clearly.  I have included a link to a
> quickstart demonstrating this with the classes and interface I created.
> With the quickstart I have put in some println's to make it easy to follow
> what's being called and when.
>
> Please let me know if I have missed an easier way to do this, or if any of
> you committers would be interested in working this funcitonality into the
> Wicket codebase.
>
> QUICKSTART HERE:
> http://cosmiao.com/jps/wicket-quickstart.zip
> It is all demonstrated on the Home page.
>
> Thanks,
> Jamie
> --
> View this message in context:
> http://www.nabble.com/Wicket---Ajax%28Fallback%29Button-and-Form---possible-solution-to-problem-tp20373644p20373644.html
> Sent from the Wicket - User mailing list archive at Nabble.com.
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@wicket.apache.org
> For additional commands, e-mail: users-help@wicket.apache.org
>
>