Martin,
I'll try once again to explain my problem and if it's still unclear I'll
make the quickstart.
What you say is right, the sequence of events is as you said.
My problem is that everything happens in AbstractRepeater#onBeforeRender().
So I have to put my code "attachValidationErrors" either before or after
AbstractRepeater#onBeforeRender().
If I put it before, the form components have not yet been created
(onPopulate() has not yet been called).
If I put it after, the componentPostOnBeforeRenderListeners have already
run so the ErrorDecorator thinks there are no errors.
What I need is a way for my code to run *after* onPopulate() but *before*
onBeforeRenderChildren(). There is no such hook though.
Let me also expand my pseudocode a bit in case this helps:
class MyPage extends WebPage {
pyblic MyPage() {
Form form = new Form("form", model) {
override onBeforeRender() {
attachValidationErrors();
onBeforeRender();
}
};
add(form);
ListView list = new ListView("list", model2) {
public populateItem(ListItem listItem) {
add(new TextField("name", new PropertyModel(model2, "name")));
}
}
form.add(list);
}
void attachValidationErrors() {
form.visitChildren(FormComponent.class, new
IVisitor<FormComponent,Void>() {
void component(FormComponent<?> obj, IVisit<Void> visit) {
if (obj.getId().equals("name") /* and some other complex
logic here */) {
obj.error("Please provide a name");
}
}
});
}
I think this makes my problem quite evident. I can't find the right place
to put the call to attachValidationErrors().
Or perhaps I need a different implements for FormErrorDecorator.
On Mon, Nov 24, 2014 at 5:13 PM, Martin Grigorov <[email protected]>
wrote:
> Hi,
>
> Maybe I miss something from your description but I think ListView's items
> should have their #onBeforeRender() method called as any other component in
> the tree.
>
> org.apache.wicket.markup.repeater.AbstractRepeater#onBeforeRender() first
> calls #onPopulate() (where ListView adds its children) and then calls
> super.onBeforeRender()
> where org.apache.wicket.MarkupContainer#onBeforeRenderChildren() that calls
> #onBeforeRender() for all children components. So
> IComponentOnBeforeRenderListener should be notified.
>
> Maybe a quickstart will make it easier for understanding where is the
> problem.
>
>
> On Mon, Nov 24, 2014 at 4:52 PM, mscoon <[email protected]> wrote:
>
> > Martin,
> >
> > Application#getComponentPostOnBeforeRenderListeners is how I am already
> > registering my FormErrorDecorator.
> >
> > Attaching the validation errors after super.onBeforeRender() does not
> work
> > even for components that are statically added and not part of a list
> view.
> >
> > Here's some psuedocode:
> >
> > Form form = new Form("form", model) {
> > protected void onBeforeRender() {
> > super.onBeforeRender();
> > attachValidationErrors();
> > }
> > }
> >
> > super.onBeforeRender() calls onBeforeRender() on all children which in
> turn
> > calls both the componentPreOnBeforeRenderListeners and the
> > componentPostOnBeforeRenderListeners. So by the time
> > attachValidationErrors() is called the error decorator has run and
> finished
> > (and done nothing as it found no errors).
> >
> > If I move attachValidationErrors before super.onBeforeRender(), then it
> > works for statically added form components. It does not work for
> components
> > within ListViews because populateItem has not yet been called.
> >
> > I could move some of the error attaching logic within populateItem but
> this
> > is ugly and leads to code duplication (as populateItem will not always be
> > called because I need setReuseItems(true)).
> >
> > Any other ideas?
> >
> >
> >
> >
> >
> > On Mon, Nov 24, 2014 at 3:23 PM, Martin Grigorov <[email protected]>
> > wrote:
> >
> > > Hi,
> > >
> > > Try with org.apache.wicket.Application#getComponent*Post*
> > > OnBeforeRenderListeners()
> > >
> > > Martin Grigorov
> > > Wicket Training and Consulting
> > > https://twitter.com/mtgrigorov
> > >
> > > On Mon, Nov 24, 2014 at 2:50 PM, mscoon <[email protected]> wrote:
> > >
> > > > Hi all,
> > > >
> > > > I am using a FormErrorDecorator that implements an
> > > > IComponentOnBeforeRenderListener in order to automatically attach a
> css
> > > > class to form components with validation errors (see
> > > >
> > > >
> > >
> >
> https://cwiki.apache.org/confluence/display/WICKET/Automatic+styling+of+form+errors
> > > > ).
> > > >
> > > > Sometimes I want to manually add errors to form components and I was
> > > doing
> > > > that in onBeforeRender() before the call to super.onBeforeRender(). I
> > do
> > > > this because sometimes the object being edited is in an invalid state
> > > and I
> > > > want to show the validation errors right when the form opens and not
> > > after
> > > > a submit. This is working fine for most cases as the errors are
> > attached
> > > to
> > > > the form components before the FormErrorDecorator runs.
> > > >
> > > > However, form components inside a list view are not created until the
> > end
> > > > of ListView.onBeforeRender(). This means that I cannot attach errors
> > > before
> > > > this step because the list view items don't yet exist, and if I
> attach
> > > them
> > > > after onBeforeRender they are not picked up by the
> FormErrorDecorator.
> > > >
> > > > Any ideas?
> > > >
> > > > Thanks,
> > > > Marios
> > > >
> > >
> >
>