I have a wicket form which contains many TextField input components. There's a Validator attached to most of these inputs.
Suppose I've entered 50 values, and one of those fails a range validator. Wicket then generates an error feedback message, but also does not update the models associated with each component. Result is that I lose all 50 values I just entered, and have to type them in again.
My question is, can I tell Wicket to update the models of those components which had valid values, but just report an error for the bad value?
Digging around in the framwork, I noticed this code fragment in FormComponent, which seems to be indicating that if there is an error, then don't update the model.
public final void processInput()
{
inputChanged();
validate();
if (hasErrorMessage())
{
invalid();
}
else
{
valid();
updateModel();
}
}
Is there any way to customise this behaviour, and achieve my aim of retaining all valid values?
I'd bet that FormComponent.processInput()
is not being called at all here. When you submit the Form
, Form.process()
gets called. There, it will call Form.validate()
, which in turn will call Form.validateComponents()
, ultimately using FormComponent.validate()
.
The problem you're having here is the global handling in Form.process()
. The form submits fully, or not at all. When a FormComponent.validate()
fails, Form.hasError()
will return true
, and therefore Form.process()
will never update any of the models.
You could:
FormValidator
. There you can choose to update the Models of those FormComponents
that pass their validations. Form.onError()
and use a visitor there to update the models of valid FormComponents
.Form.process()
and modify the // If a validation error occurred
branch to use your own methods to mark components as valid/invalid, and update (or not) model objects, depending on the FormComponent
having errors. FormComponent.hasErrorMessage()
will tell you if validation failed on a certain FormComponent
.UPDATE
After discussing the reasons why user input was lost with the OP, it turned out that the FormComponents
were being added in a ListView
that did not have setReuseItems
set to true
. This was causing FormComponents
to be created anew on each ListView.populateItem()
, therefore losing all user input.
More information on the nature of this problem can be found here:
There are however a few provisions you have to take care of when using a repeater in the form. Usually repeaters clear out their items at the beginning of every request, when inside a form this is usually undesirable because you want to preserve the old items because you want them to keep their state as opposed to being recreated fresh.
For example, if you use ListView, you should call ListView.setReuseItems(true) inside the form so that it preserves old items instead of always creating new ones everytime.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With