You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@wicket.apache.org by mscoon <ms...@gmail.com> on 2014/11/24 13:50:16 UTC

IComponentOnBeforeRenderListener and ListView

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

Re: IComponentOnBeforeRenderListener and ListView

Posted by mscoon <ms...@gmail.com>.
On Tue, Nov 25, 2014 at 11:40 PM, Martin Grigorov <mg...@apache.org>
wrote:

> On Tue, Nov 25, 2014 at 11:33 PM, mscoon <ms...@gmail.com> wrote:
>
> > I don't want to use an IComponentOnBeforeRenderListener as it is an
> > application wide facility whereas what I'm doing applies to a couple of
> > pages only.
> >
> > But you suggestion gave me an idea. I am now using a behavior which I add
> > to all form components in ListView#populateItem(). The behavior marks the
> > components as invalid in onConfigure() which comes before
> onBeforeRender()
> > and hence before the IComponentOnBeforeRenderListener.
> >
> > The problem with this solution is that this code is much more complicated
> > than what I was doing originally. Now I have to put the validation errors
> > in a transient field which is set in the form's onConfigure() method, and
> > use this field to retrieve the errors from within Behavior#onConfigure().
> > What I tried to do originally was much cleaner, the model object was
> > validated and the components invalidated from within a single method.
> >
> >
>
> > It does seem like AbstractRepeater should have a postOnPopulate() method
> to
> > allow client code to access the created components before
> onBeforeRender()
> > is executed, don't you think?
> >
>
> You can use populateItem() for this, no ?
>


​Not all of them at once, no. You only get to access the components within
a single ​ListItem.

But as we talk about it I see now that this is a very specific and limited
use case, probably not worth considering changes to wicket for this.

Thanks for your time!

Re: IComponentOnBeforeRenderListener and ListView

Posted by Martin Grigorov <mg...@apache.org>.
On Tue, Nov 25, 2014 at 11:33 PM, mscoon <ms...@gmail.com> wrote:

> I don't want to use an IComponentOnBeforeRenderListener as it is an
> application wide facility whereas what I'm doing applies to a couple of
> pages only.
>
> But you suggestion gave me an idea. I am now using a behavior which I add
> to all form components in ListView#populateItem(). The behavior marks the
> components as invalid in onConfigure() which comes before onBeforeRender()
> and hence before the IComponentOnBeforeRenderListener.
>
> The problem with this solution is that this code is much more complicated
> than what I was doing originally. Now I have to put the validation errors
> in a transient field which is set in the form's onConfigure() method, and
> use this field to retrieve the errors from within Behavior#onConfigure().
> What I tried to do originally was much cleaner, the model object was
> validated and the components invalidated from within a single method.
>
>

> It does seem like AbstractRepeater should have a postOnPopulate() method to
> allow client code to access the created components before onBeforeRender()
> is executed, don't you think?
>

You can use populateItem() for this, no ?


>
> On Tue, Nov 25, 2014 at 4:29 PM, Martin Grigorov <mg...@apache.org>
> wrote:
>
> > OK, but isn't it possible to mark the form components as invalid with
> > IComponentOnBeforeRenderListener too ?
> > Just add the new IComponentOnBeforeRenderListener in the collection
> before
> > FormErrorDecorator.
> >
> > Martin Grigorov
> > Wicket Training and Consulting
> > https://twitter.com/mtgrigorov
> >
> > On Tue, Nov 25, 2014 at 4:15 PM, mscoon <ms...@gmail.com> wrote:
> >
> > > attachValidationErrors has nothing to do with FormErrorDecorator. It is
> > > just some code that adds validation errors to some form components.
> > >
> > > I use it because I want to show validation errors right when then form
> > > opens, and not after a submit. For instance if the user loads a record
> > for
> > > editing, and this record has some wrong data in it, I want to
> immediately
> > > show the validation errors when the page renders and not have to wait
> > until
> > > a submit.
> > >
> > > On Tue, Nov 25, 2014 at 11:50 AM, Martin Grigorov <
> mgrigorov@apache.org>
> > > wrote:
> > >
> > > > Hi,
> > > >
> > > > On Mon, Nov 24, 2014 at 10:34 PM, mscoon <ms...@gmail.com> wrote:
> > > >
> > > > > 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();
> > > > >
> > > >
> > > > Why do you need to call that here at all ? Why you want to traverse
> the
> > > > sub-tree manually ?
> > > >
> > > > By using IComponentOnBeforeRenderListener you are being notified for
> > each
> > > > and every Component in the component tree.
> > > > So your listener should just check whether the component is an
> instance
> > > of
> > > > FormComponent and if its name matches (and the other complex logic
> you
> > > > have) then report the error.
> > > >
> > > >
> > > > >            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 <
> > mgrigorov@apache.org
> > > >
> > > > > 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 <ms...@gmail.com>
> 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 <
> > > > mgrigorov@apache.org
> > > > > >
> > > > > > > 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 <ms...@gmail.com>
> > > 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
> > > > > > > > >
> > > > > > > >
> > > > > > >
> > > > > >
> > > > >
> > > >
> > >
> >
>

Re: IComponentOnBeforeRenderListener and ListView

Posted by mscoon <ms...@gmail.com>.
I don't want to use an IComponentOnBeforeRenderListener as it is an
application wide facility whereas what I'm doing applies to a couple of
pages only.

But you suggestion gave me an idea. I am now using a behavior which I add
to all form components in ListView#populateItem(). The behavior marks the
components as invalid in onConfigure() which comes before onBeforeRender()
and hence before the IComponentOnBeforeRenderListener.

The problem with this solution is that this code is much more complicated
than what I was doing originally. Now I have to put the validation errors
in a transient field which is set in the form's onConfigure() method, and
use this field to retrieve the errors from within Behavior#onConfigure().
What I tried to do originally was much cleaner, the model object was
validated and the components invalidated from within a single method.

It does seem like AbstractRepeater should have a postOnPopulate() method to
allow client code to access the created components before onBeforeRender()
is executed, don't you think?

On Tue, Nov 25, 2014 at 4:29 PM, Martin Grigorov <mg...@apache.org>
wrote:

> OK, but isn't it possible to mark the form components as invalid with
> IComponentOnBeforeRenderListener too ?
> Just add the new IComponentOnBeforeRenderListener in the collection before
> FormErrorDecorator.
>
> Martin Grigorov
> Wicket Training and Consulting
> https://twitter.com/mtgrigorov
>
> On Tue, Nov 25, 2014 at 4:15 PM, mscoon <ms...@gmail.com> wrote:
>
> > attachValidationErrors has nothing to do with FormErrorDecorator. It is
> > just some code that adds validation errors to some form components.
> >
> > I use it because I want to show validation errors right when then form
> > opens, and not after a submit. For instance if the user loads a record
> for
> > editing, and this record has some wrong data in it, I want to immediately
> > show the validation errors when the page renders and not have to wait
> until
> > a submit.
> >
> > On Tue, Nov 25, 2014 at 11:50 AM, Martin Grigorov <mg...@apache.org>
> > wrote:
> >
> > > Hi,
> > >
> > > On Mon, Nov 24, 2014 at 10:34 PM, mscoon <ms...@gmail.com> wrote:
> > >
> > > > 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();
> > > >
> > >
> > > Why do you need to call that here at all ? Why you want to traverse the
> > > sub-tree manually ?
> > >
> > > By using IComponentOnBeforeRenderListener you are being notified for
> each
> > > and every Component in the component tree.
> > > So your listener should just check whether the component is an instance
> > of
> > > FormComponent and if its name matches (and the other complex logic you
> > > have) then report the error.
> > >
> > >
> > > >            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 <
> mgrigorov@apache.org
> > >
> > > > 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 <ms...@gmail.com> 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 <
> > > mgrigorov@apache.org
> > > > >
> > > > > > 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 <ms...@gmail.com>
> > 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
> > > > > > > >
> > > > > > >
> > > > > >
> > > > >
> > > >
> > >
> >
>

Re: IComponentOnBeforeRenderListener and ListView

Posted by Martin Grigorov <mg...@apache.org>.
OK, but isn't it possible to mark the form components as invalid with
IComponentOnBeforeRenderListener too ?
Just add the new IComponentOnBeforeRenderListener in the collection before
FormErrorDecorator.

Martin Grigorov
Wicket Training and Consulting
https://twitter.com/mtgrigorov

On Tue, Nov 25, 2014 at 4:15 PM, mscoon <ms...@gmail.com> wrote:

> attachValidationErrors has nothing to do with FormErrorDecorator. It is
> just some code that adds validation errors to some form components.
>
> I use it because I want to show validation errors right when then form
> opens, and not after a submit. For instance if the user loads a record for
> editing, and this record has some wrong data in it, I want to immediately
> show the validation errors when the page renders and not have to wait until
> a submit.
>
> On Tue, Nov 25, 2014 at 11:50 AM, Martin Grigorov <mg...@apache.org>
> wrote:
>
> > Hi,
> >
> > On Mon, Nov 24, 2014 at 10:34 PM, mscoon <ms...@gmail.com> wrote:
> >
> > > 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();
> > >
> >
> > Why do you need to call that here at all ? Why you want to traverse the
> > sub-tree manually ?
> >
> > By using IComponentOnBeforeRenderListener you are being notified for each
> > and every Component in the component tree.
> > So your listener should just check whether the component is an instance
> of
> > FormComponent and if its name matches (and the other complex logic you
> > have) then report the error.
> >
> >
> > >            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 <mgrigorov@apache.org
> >
> > > 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 <ms...@gmail.com> 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 <
> > mgrigorov@apache.org
> > > >
> > > > > 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 <ms...@gmail.com>
> 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
> > > > > > >
> > > > > >
> > > > >
> > > >
> > >
> >
>

Re: IComponentOnBeforeRenderListener and ListView

Posted by mscoon <ms...@gmail.com>.
attachValidationErrors has nothing to do with FormErrorDecorator. It is
just some code that adds validation errors to some form components.

I use it because I want to show validation errors right when then form
opens, and not after a submit. For instance if the user loads a record for
editing, and this record has some wrong data in it, I want to immediately
show the validation errors when the page renders and not have to wait until
a submit.

On Tue, Nov 25, 2014 at 11:50 AM, Martin Grigorov <mg...@apache.org>
wrote:

> Hi,
>
> On Mon, Nov 24, 2014 at 10:34 PM, mscoon <ms...@gmail.com> wrote:
>
> > 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();
> >
>
> Why do you need to call that here at all ? Why you want to traverse the
> sub-tree manually ?
>
> By using IComponentOnBeforeRenderListener you are being notified for each
> and every Component in the component tree.
> So your listener should just check whether the component is an instance of
> FormComponent and if its name matches (and the other complex logic you
> have) then report the error.
>
>
> >            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 <mg...@apache.org>
> > 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 <ms...@gmail.com> 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 <
> mgrigorov@apache.org
> > >
> > > > 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 <ms...@gmail.com> 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
> > > > > >
> > > > >
> > > >
> > >
> >
>

Re: IComponentOnBeforeRenderListener and ListView

Posted by Martin Grigorov <mg...@apache.org>.
Hi,

On Mon, Nov 24, 2014 at 10:34 PM, mscoon <ms...@gmail.com> wrote:

> 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();
>

Why do you need to call that here at all ? Why you want to traverse the
sub-tree manually ?

By using IComponentOnBeforeRenderListener you are being notified for each
and every Component in the component tree.
So your listener should just check whether the component is an instance of
FormComponent and if its name matches (and the other complex logic you
have) then report the error.


>            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 <mg...@apache.org>
> 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 <ms...@gmail.com> 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 <mgrigorov@apache.org
> >
> > > 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 <ms...@gmail.com> 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
> > > > >
> > > >
> > >
> >
>

Re: IComponentOnBeforeRenderListener and ListView

Posted by mscoon <ms...@gmail.com>.
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 <mg...@apache.org>
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 <ms...@gmail.com> 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 <mg...@apache.org>
> > 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 <ms...@gmail.com> 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
> > > >
> > >
> >
>

Re: IComponentOnBeforeRenderListener and ListView

Posted by Martin Grigorov <mg...@apache.org>.
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 <ms...@gmail.com> 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 <mg...@apache.org>
> 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 <ms...@gmail.com> 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
> > >
> >
>

Re: IComponentOnBeforeRenderListener and ListView

Posted by mscoon <ms...@gmail.com>.
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 <mg...@apache.org>
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 <ms...@gmail.com> 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
> >
>

Re: IComponentOnBeforeRenderListener and ListView

Posted by Martin Grigorov <mg...@apache.org>.
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 <ms...@gmail.com> 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
>