Looking at the wicket source regarding this, I don't think it's possible to get 
the desired behaviour.

It looks like a new hook is needed in FormComponent.validate() that is called 
before any of the other logic.

Something like FormComponent.isUsed(). If this returns false, just exit the 
validate() methods.

Default FormComponent implementation would return true for this method, but it 
can be overriden to provide the desired behaviour.

As I understand the submit/validate/bind sequence, this would mean that the 
form component's raw input is updated (which makes sense), but validation/model 
object doesn't happen.

Is this feasible, and would it impact elsewhere?


Here's an update of my previous example showing how it would be used:

private class TestForm extends Form {

  private String always;
  private boolean useOptional = false;
  private String optional;

  public TestForm(String id) {
    super(id);

    add( new TextField("always", new PropertyModel(this, 
"always")).setRequired(true) );
    final CheckBox useOptionalCheck = new CheckBox( "useOptional", new 
PropertyModel(this, "useOptional") );
    add( useOptionalCheck );
    add( new TextField("optional", new PropertyModel(this, "optional")) {
      @Override
      public boolean isUsed() {
        return ((Boolean)useOptionalCheck.getConvertedInput()).booleanValue();
      }

      @Override
      public boolean isRequired() {
        isUsed();
      }      
    }.add(MinimumLengthValidator.minimumLength(3)) );
  }

}


----- Original Message -----
From: "Xavier López" <xavil...@gmail.com>
To: users@wicket.apache.org
Sent: Thursday, 3 June, 2010 2:56:33 PM
Subject: Re: Show/hide form components best practice

I'm with you on this one, this code feels like doing something that it
shouldn't, looks kind of bloated for such a simple and common
requirement. Maybe we need some stuffing of nice, pre-canned
FormValidators ? :)

The problem with wicket's validators, as I see it, is that they are at a
Component level. They do their job based on that component's
input/state, only. In fact, they are called in Form's
validateComponents() one by one in
a traversal. If another component's input or state is required to
perform the validation, i'd do it inside a FormValidator. That copes
with your
requirement of "ignore the input for this component completely",
although I
don't know how would that be achieved.

Of course, in all those comments, I assume you can not rely on
javascript nor ajax to perform those validations, in which case the
visibility approach
simply couldn't work.

Cheers,
Xavier

2010/6/3 Iain Reddick <iain.redd...@beatsystems.com>

> The problem with this approach is that you throw away all the nice,
> re-usable pre-canned validators that wicket has, and that it seems
> very "wrong".
>
> I'd actually push the behaviour I would like to see even further - in
> the example I gave, I don't even want the optional field to update
> it's model
> when the check box isn't selected.
>
> Effectively, I want to be able to specify logic which says "ignore the
> input for this component completely". Currently, the only way to do
> this is
> by using component visibility (unless I'm completely wrong on this).
>
> Xavier López wrote:
>
>> Hi Iain,
>>
>> I would do it like this, with a FormValidator. I moved the minimum
>> length validation also to the formValidator, because doing it with a
>> MinimumLenghtValidator would trigger it before the formValidator
>> executes, and may raise errors when the input is not valid (i.e. not
>> mandatory) :
>>
>> private class TestForm extends Form {
>>
>> IModel modelAlways;
>> IModel modelCheckOptional;
>> IModel modelOptional;
>>
>>  public TestForm(String id) {
>>   super(id);
>>
>>   modelAlways = new Model("");
>>   modelCheckOptional = Boolean.FALSE;
>>   modelOptional = new Model("");
>>   final TextField alwaysTextfield = new TextField("always",
>>   modelAlways); alwaysTextField.setRequired(true);
>>   add(alwaysTextField); final CheckBox useOptionalCheck = new
>>   CheckBox( "useOptional",
>> modelCheckOptional);
>>   add( useOptionalCheck );
>>   final TextField optionalTextField = new TextField("optional",
>> modelOptional);
>>   add(optionalTextField);
>>
>>   add(new IFormValidator(){
>>      protected FormComponent getDependentFormComponents(){ return
>>      null; }
>>      public boolean validate(Form f){
>>          if
>>          (Boolean.TRUE.equals(useOptionalCheck.getConvertedInput()){
>>                String optionalValue =
>> optionalTextField.getConvertedInput();
>>                if (Strings.isEmpty(optionalValue ){
>>                       error ("field optional is required");
>>                } else if (optionalValue.length < 3){
>>                       error ("optional value's length must be at
>>                       least 3);
>>                }
>>          }.
>> } });
>>
>> Cheers,
>> Xavier
>>
>> 2010/6/2 Iain Reddick <iain.redd...@beatsystems.com>
>>
>>
>>
>>> Here's some example code (wicket 1.3.x):
>>>
>>> Java:
>>>
>>> private class TestForm extends Form {
>>>
>>>  private String always;
>>>  private boolean useOptional = false;
>>>  private String optional;
>>>
>>>  public TestForm(String id) {
>>>   super(id);
>>>
>>>   add( new TextField("always", new PropertyModel(this,
>>> "always")).setRequired(true) );
>>>   final CheckBox useOptionalCheck = new CheckBox( "useOptional", new
>>> PropertyModel(this, "useOptional") );
>>>   add( useOptionalCheck );
>>>   add( new TextField("optional", new PropertyModel(this,
>>>   "optional")) {
>>>     @Override public boolean isRequired() {
>>>       return
>>> ((Boolean)useOptionalCheck.getConvertedInput()).booleanValue();
>>>     }
>>>   }.add(MinimumLengthValidator.minimumLength(3)) );
>>>  }
>>>
>>> }
>>>
>>> Markup:
>>>
>>> <form wicket:id="testForm">
>>>  <input wicket:id="always" type="text" />
>>>  <input wicket:id="useOptional" type="checkbox" />
>>>  <input wicket:id="optional" type="text" />
>>>  <input type="submit" />
>>> </form>
>>>
>>> How can I express that I want the optional text field to only be
>>> used when
>>> the checkbox is selected?
>>>
>>> ----- Original Message -----
>>> From: "Igor Vaynberg" <igor.vaynb...@gmail.com>
>>> To: users@wicket.apache.org
>>> Sent: Wednesday, 2 June, 2010 4:00:57 PM
>>> Subject: Re: Show/hide form components best practice
>>>
>>> if the form contains all the state then the answer is simple: write
>>> a bit of javascript that does it for you.
>>>
>>> -igor
>>>
>>> On Wed, Jun 2, 2010 at 2:53 AM, Iain Reddick
>>> <iain.redd...@beatsystems.com> wrote:
>>>
>>>
>>>> That's just a server round-trip on client-side state changem, which
>>>> is basically (1) in my initial list.
>>>>
>>>> Basically, this type of form behaviour is very common and the
>>>> question of how to implement it with Wicket has been raised by
>>>> every developer
>>>> I know
>>>> who has worked with the framework.
>>>>
>>>> I know that Wicket generally works best when you round-trip
>>>> client-side state changes to the server, but I think that in this
>>>> situation it is silly,
>>>> as the submitted form contains all the required state.
>>>>
>>>> Jeremy Thomerson wrote:
>>>>
>>>>
>>>>> return true from wantOnSelectionChangedNotifications and put your
>>>>> visibility changing code in onSelectionChanged
>>>>>
>>>>>
>>>>> <
>>>>>
>>>>>
>>>>
>>> http://wicket.apache.org/docs/1.4/org/apache/wicket/markup/html/form/CheckGroup.html#wantOnSelectionChangedNotifications()<http://wicket.apache.org/docs/1.4/org/apache/wicket/markup/html/form/CheckGroup.html#wantOnSelectionChangedNotifications%28%29>
>>> <
>>> http://wicket.apache.org/docs/1.4/org/apache/wicket/markup/html/form/CheckGroup.html#wantOnSelectionChangedNotifications%28%29
>>> >
>>>
>>>
>>>>
>>>>>
>>>>
>>> http://wicket.apache.org/docs/1.4/org/apache/wicket/markup/html/form/CheckGroup.html#wantOnSelectionChangedNotifications()<http://wicket.apache.org/docs/1.4/org/apache/wicket/markup/html/form/CheckGroup.html#wantOnSelectionChangedNotifications%28%29>
>>> <
>>> http://wicket.apache.org/docs/1.4/org/apache/wicket/markup/html/form/CheckGroup.html#wantOnSelectionChangedNotifications%28%29
>>> >
>>>
>>>
>>>
>>>> On Tue, Jun 1, 2010 at 5:37 AM, Iain Reddick
>>>>> <iain.redd...@beatsystems.com>wrote:
>>>>>
>>>>>
>>>>>
>>>>>
>>>>>> Say I have a form with a check box that, when checked, shows some
>>>>>> other field (i.e. it controls the visibility of other form
>>>>>> components).
>>>>>>
>>>>>> What is the best approach to handling this?
>>>>>>
>>>>>> From what I understand, you have 3 options:
>>>>>>
>>>>>> 1. Add ajax behaviour to the check box (re-render relevant
>>>>>> components). 2. Add javascript from the Java code (e.g. add some
>>>>>> kind of show/hide
>>>>>> behaviour). 3. Add javascript directly to the HTML.
>>>>>>
>>>>>> What are peoples experiences of the 3 methods, and which is best?
>>>>>>
>>>>>> ---------------------------------------------------------------------
>>>>>> To unsubscribe, e-mail: users-unsubscr...@wicket.apache.org
>>>>>> For additional commands, e-mail: users-h...@wicket.apache.org
>>>>>>
>>>>>>
>>>>>>
>>>>>>
>>>>>>
>>>>>
>>>>>
>>>>>
>>>>
>>>>
>>> ---------------------------------------------------------------------
>>> To unsubscribe, e-mail: users-unsubscr...@wicket.apache.org
>>> For additional commands, e-mail: users-h...@wicket.apache.org
>>>
>>> ---------------------------------------------------------------------
>>> To unsubscribe, e-mail: users-unsubscr...@wicket.apache.org
>>> For additional commands, e-mail: users-h...@wicket.apache.org
>>>
>>>
>>>
>>>
>>
>>
>>
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscr...@wicket.apache.org
> For additional commands, e-mail: users-h...@wicket.apache.org
>
>

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

Reply via email to