On Tue, Nov 25, 2014 at 11:33 PM, mscoon <msc...@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 <mgrigo...@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 <msc...@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 <
> mgrigo...@apache.org>
> > > wrote:
> > >
> > > > Hi,
> > > >
> > > > On Mon, Nov 24, 2014 at 10:34 PM, mscoon <msc...@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 <
> > mgrigo...@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 <msc...@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 <
> > > > mgrigo...@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 <msc...@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
> > > > > > > > >
> > > > > > > >
> > > > > > >
> > > > > >
> > > > >
> > > >
> > >
> >
>

Reply via email to