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