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 <[email protected]>
wrote:

> Hi,
>
> On Mon, Nov 24, 2014 at 10:34 PM, mscoon <[email protected]> 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 <[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
> > > > > >
> > > > >
> > > >
> > >
> >
>

Reply via email to