Undesirable behavior of AutoLabelMarker

classic Classic list List threaded Threaded
8 messages Options
Reply | Threaded
Open this post in threaded view
|

Undesirable behavior of AutoLabelMarker

mscoon
Hi all,

We have an outer form and an inner form. The inner form contains some form
components which all have an AjaxFormSubmitBehavior in order to update each
- other when the user changes one of them.

The actual submitting button is in the outer form.

When the AjaxFormSubmitBehavior runs and some components are invalid,
AutoLabelMarker is called and updates the label classes according to the
component's validation state (valid/invalid) (and also required/enabled
state). We do not want this to happen because the user is in the process of
filling in the form, and we think it's confusing to have the labels of some
components change color. This should only happen when the user has clicked
the submitting button.

Whats-more the label classes are updated for all form components, ignoring
whether the components have been added to the AjaxRequestTarget in
AjaxFormSubmitBehavior.onSubmit/onError.

Can someone explain the reasoning behind AutoLabelMarker always updating
all form component labels in every ajax request? Shouldn't labels be
repainted after the ajax request only if their controls are repainted -
i.e. added to the AjaxRequestTarget?

Apparently we can remove the AutoLabelMarker from all form components. Is
this what we should do? Isn't there a cleaner way?

Thanks in advance,
Marios
Reply | Threaded
Open this post in threaded view
|

Re: Undesirable behavior of AutoLabelMarker

Martin Grigorov-4
Hi,

Why do you use AjaxFormSubmitBehavior ? It submits the whole form, i.e. all
its form components.
I think you want to use AjaxForm[Choice]ComponentUpdatingBehavior - it will
submit only the value of the modified field.

On Fri, Feb 8, 2019 at 2:57 PM mscoon <[hidden email]> wrote:

> Hi all,
>
> We have an outer form and an inner form. The inner form contains some form
> components which all have an AjaxFormSubmitBehavior in order to update each
> - other when the user changes one of them.
>
> The actual submitting button is in the outer form.
>
> When the AjaxFormSubmitBehavior runs and some components are invalid,
> AutoLabelMarker is called and updates the label classes according to the
> component's validation state (valid/invalid) (and also required/enabled
> state). We do not want this to happen because the user is in the process of
> filling in the form, and we think it's confusing to have the labels of some
> components change color. This should only happen when the user has clicked
> the submitting button.
>
> Whats-more the label classes are updated for all form components, ignoring
> whether the components have been added to the AjaxRequestTarget in
> AjaxFormSubmitBehavior.onSubmit/onError.
>
> Can someone explain the reasoning behind AutoLabelMarker always updating
> all form component labels in every ajax request? Shouldn't labels be
> repainted after the ajax request only if their controls are repainted -
> i.e. added to the AjaxRequestTarget?
>
> Apparently we can remove the AutoLabelMarker from all form components. Is
> this what we should do? Isn't there a cleaner way?
>
> Thanks in advance,
> Marios
>
Reply | Threaded
Open this post in threaded view
|

Re: Undesirable behavior of AutoLabelMarker

mscoon
Hi Martin,

The form reloads the entity from the database (it uses a kind of loadable
detachable model) at each ajax request, so it does not remember the values
for the fields that have been modified in previous requests if we use
AjaxForm[Choice]ComponentUpdatingBehavior. This is why we use
AjaxFormSubmitBehavior.

We could alter the form somehow to use AjaxForm[Choice]ComponentUpdat
ingBehavior, but still... aren't my points valid?

On Fri, Feb 8, 2019 at 9:26 PM Martin Grigorov <[hidden email]> wrote:

> Hi,
>
> Why do you use AjaxFormSubmitBehavior ? It submits the whole form, i.e. all
> its form components.
> I think you want to use AjaxForm[Choice]ComponentUpdatingBehavior - it will
> submit only the value of the modified field.
>
> On Fri, Feb 8, 2019 at 2:57 PM mscoon <[hidden email]> wrote:
>
> > Hi all,
> >
> > We have an outer form and an inner form. The inner form contains some
> form
> > components which all have an AjaxFormSubmitBehavior in order to update
> each
> > - other when the user changes one of them.
> >
> > The actual submitting button is in the outer form.
> >
> > When the AjaxFormSubmitBehavior runs and some components are invalid,
> > AutoLabelMarker is called and updates the label classes according to the
> > component's validation state (valid/invalid) (and also required/enabled
> > state). We do not want this to happen because the user is in the process
> of
> > filling in the form, and we think it's confusing to have the labels of
> some
> > components change color. This should only happen when the user has
> clicked
> > the submitting button.
> >
> > Whats-more the label classes are updated for all form components,
> ignoring
> > whether the components have been added to the AjaxRequestTarget in
> > AjaxFormSubmitBehavior.onSubmit/onError.
> >
> > Can someone explain the reasoning behind AutoLabelMarker always updating
> > all form component labels in every ajax request? Shouldn't labels be
> > repainted after the ajax request only if their controls are repainted -
> > i.e. added to the AjaxRequestTarget?
> >
> > Apparently we can remove the AutoLabelMarker from all form components. Is
> > this what we should do? Isn't there a cleaner way?
> >
> > Thanks in advance,
> > Marios
> >
>
Reply | Threaded
Open this post in threaded view
|

Re: Undesirable behavior of AutoLabelMarker

Martin Grigorov-4
Hi,

On Sun, Feb 10, 2019 at 10:29 PM mscoon <[hidden email]> wrote:

> Hi Martin,
>
> The form reloads the entity from the database (it uses a kind of loadable
> detachable model) at each ajax request, so it does not remember the values
> for the fields that have been modified in previous requests if we use
> AjaxForm[Choice]ComponentUpdatingBehavior. This is why we use
> AjaxFormSubmitBehavior.
>
> We could alter the form somehow to use AjaxForm[Choice]ComponentUpdat
> ingBehavior, but still... aren't my points valid?
>

I do not know. There is no class AutoLabelMarker in Wicket distribution. I
have no idea what it is and how it works.

It would be better to explain us what you want to achieve and then we can
help you implement it.

From the information we have at the moment I think you need to keep the
entity being edited as a property of the form/panel/page.
AjaxFormComponentUpdatingBehavior will validate and modify it. At the end
when the form submit button is pressed you should do the final checks and
store it in the database.


>
> On Fri, Feb 8, 2019 at 9:26 PM Martin Grigorov <[hidden email]>
> wrote:
>
> > Hi,
> >
> > Why do you use AjaxFormSubmitBehavior ? It submits the whole form, i.e.
> all
> > its form components.
> > I think you want to use AjaxForm[Choice]ComponentUpdatingBehavior - it
> will
> > submit only the value of the modified field.
> >
> > On Fri, Feb 8, 2019 at 2:57 PM mscoon <[hidden email]> wrote:
> >
> > > Hi all,
> > >
> > > We have an outer form and an inner form. The inner form contains some
> > form
> > > components which all have an AjaxFormSubmitBehavior in order to update
> > each
> > > - other when the user changes one of them.
> > >
> > > The actual submitting button is in the outer form.
> > >
> > > When the AjaxFormSubmitBehavior runs and some components are invalid,
> > > AutoLabelMarker is called and updates the label classes according to
> the
> > > component's validation state (valid/invalid) (and also required/enabled
> > > state). We do not want this to happen because the user is in the
> process
> > of
> > > filling in the form, and we think it's confusing to have the labels of
> > some
> > > components change color. This should only happen when the user has
> > clicked
> > > the submitting button.
> > >
> > > Whats-more the label classes are updated for all form components,
> > ignoring
> > > whether the components have been added to the AjaxRequestTarget in
> > > AjaxFormSubmitBehavior.onSubmit/onError.
> > >
> > > Can someone explain the reasoning behind AutoLabelMarker always
> updating
> > > all form component labels in every ajax request? Shouldn't labels be
> > > repainted after the ajax request only if their controls are repainted -
> > > i.e. added to the AjaxRequestTarget?
> > >
> > > Apparently we can remove the AutoLabelMarker from all form components.
> Is
> > > this what we should do? Isn't there a cleaner way?
> > >
> > > Thanks in advance,
> > > Marios
> > >
> >
>
Reply | Threaded
Open this post in threaded view
|

Re: Undesirable behavior of AutoLabelMarker

mscoon
Ηι,

AutoLabelMarker is a public static final class defined
inside org.apache.wicket.markup.html.form.AutoLabelResolver.

What I want to achieve is the following:

I have a form with five components, C1 through C5. C5 is disabled.
When one of C1, C2, C3, C4 change, the value for C5 is computed (say with
the sum of C1+C2+C3+C4) and the component need to be updated so that the
user is shown the result before saving it to the database.
There is a button "Save" in the bottom, only when this button is pressed
should the information be stored in the database.
C1, C2, C3 and C4 do not have required validators but they are checked in
onValidateModelObjects() and if they are null, an error is shown.
The form's model is a LoadableDetachableModal holding a hibernate entity.

Let's assume we open the form and the initial values in the database are
C1=C2=C3=C4=0.
If we use AjaxFormComponentUpdatingBehavior, what happens is
1. use fills in C1 with the value 10, and presses tab, and the value sent
to the server
2. the object is loaded from the database, property C1 is set with the
component's value but it is not updated to the database
3. C5 is recomputed as C1+C2+C3+C4 = 10 and updated - everything fine up to
here
4. the model is detached
then
5. user fills in C2 with the value 20, presses tab, and the value sent to
the server
6. the object is loaded from the database, property C1 is 0 because this is
the value stored in the database (while the component C1 has the value 10
in the user's screen), property C2 is set with the component's value but it
is not updated to the database.
7. C5 is computed C1+C2+C3+C4 = 20 which is wrong, it should be 30
8. the model is detached
and so on...

This is why we chose to try the AjaxFormSubmitBehavior. We want the values
of C1, C2, C3 and C4 to be all sent to the back end with each ajax request
so that when they are summed up to compute C5 they have the values that the
user sees on the screen. However we don't want the form to be validated and
any validation errors to be shown, unless the user presses Save. As it is
now, because AjaxFormSubmitBehavior validates the form, what happens is:
1. User fills in C1 and presses tab
2. All values are sent to the server
3. C2, C3, C4's labels become red (AutoLabelMarker  gives them error class
- code is FormComponent.updateAutoLabels() called from
Form.onFormSubmitted()) since onValidateObjectModel checks them and finds
them empty

Cheers
Marios










On Mon, Feb 11, 2019 at 9:08 AM Martin Grigorov <[hidden email]>
wrote:

> Hi,
>
> On Sun, Feb 10, 2019 at 10:29 PM mscoon <[hidden email]> wrote:
>
> > Hi Martin,
> >
> > The form reloads the entity from the database (it uses a kind of loadable
> > detachable model) at each ajax request, so it does not remember the
> values
> > for the fields that have been modified in previous requests if we use
> > AjaxForm[Choice]ComponentUpdatingBehavior. This is why we use
> > AjaxFormSubmitBehavior.
> >
> > We could alter the form somehow to use AjaxForm[Choice]ComponentUpdat
> > ingBehavior, but still... aren't my points valid?
> >
>
> I do not know. There is no class AutoLabelMarker in Wicket distribution. I
> have no idea what it is and how it works.
>
> It would be better to explain us what you want to achieve and then we can
> help you implement it.
>
> From the information we have at the moment I think you need to keep the
> entity being edited as a property of the form/panel/page.
> AjaxFormComponentUpdatingBehavior will validate and modify it. At the end
> when the form submit button is pressed you should do the final checks and
> store it in the database.
>
>
> >
> > On Fri, Feb 8, 2019 at 9:26 PM Martin Grigorov <[hidden email]>
> > wrote:
> >
> > > Hi,
> > >
> > > Why do you use AjaxFormSubmitBehavior ? It submits the whole form, i.e.
> > all
> > > its form components.
> > > I think you want to use AjaxForm[Choice]ComponentUpdatingBehavior - it
> > will
> > > submit only the value of the modified field.
> > >
> > > On Fri, Feb 8, 2019 at 2:57 PM mscoon <[hidden email]> wrote:
> > >
> > > > Hi all,
> > > >
> > > > We have an outer form and an inner form. The inner form contains some
> > > form
> > > > components which all have an AjaxFormSubmitBehavior in order to
> update
> > > each
> > > > - other when the user changes one of them.
> > > >
> > > > The actual submitting button is in the outer form.
> > > >
> > > > When the AjaxFormSubmitBehavior runs and some components are invalid,
> > > > AutoLabelMarker is called and updates the label classes according to
> > the
> > > > component's validation state (valid/invalid) (and also
> required/enabled
> > > > state). We do not want this to happen because the user is in the
> > process
> > > of
> > > > filling in the form, and we think it's confusing to have the labels
> of
> > > some
> > > > components change color. This should only happen when the user has
> > > clicked
> > > > the submitting button.
> > > >
> > > > Whats-more the label classes are updated for all form components,
> > > ignoring
> > > > whether the components have been added to the AjaxRequestTarget in
> > > > AjaxFormSubmitBehavior.onSubmit/onError.
> > > >
> > > > Can someone explain the reasoning behind AutoLabelMarker always
> > updating
> > > > all form component labels in every ajax request? Shouldn't labels be
> > > > repainted after the ajax request only if their controls are
> repainted -
> > > > i.e. added to the AjaxRequestTarget?
> > > >
> > > > Apparently we can remove the AutoLabelMarker from all form
> components.
> > Is
> > > > this what we should do? Isn't there a cleaner way?
> > > >
> > > > Thanks in advance,
> > > > Marios
> > > >
> > >
> >
>
Reply | Threaded
Open this post in threaded view
|

Re: Undesirable behavior of AutoLabelMarker

Ernesto Reinaldo Barreiro-4
create an smart LDM that goes to database only once and after that keeps
value?
Reply | Threaded
Open this post in threaded view
|

Re: Undesirable behavior of AutoLabelMarker

mscoon
Hi Ernesto,

Yes, that is possible but it opens the route for lazy initialization
exceptions and such problems.

Really, why is it so hard to send multiple component values with an ajax
request? Maybe an AjaxFormComponentUpdating behavior which can update
multiple components?


On Mon, Feb 11, 2019 at 3:12 PM Ernesto Reinaldo Barreiro <
[hidden email]> wrote:

> create an smart LDM that goes to database only once and after that keeps
> value?
>
Reply | Threaded
Open this post in threaded view
|

Re: Undesirable behavior of AutoLabelMarker

Martin Grigorov-4
On Tue, Feb 12, 2019 at 10:01 AM mscoon <[hidden email]> wrote:

> Hi Ernesto,
>
> Yes, that is possible but it opens the route for lazy initialization
> exceptions and such problems.
>
> Really, why is it so hard to send multiple component values with an ajax
> request? Maybe an AjaxFormComponentUpdating behavior which can update
> multiple components?
>

You can send any payload with the Ajax request.
To do it you need to override AjaxBehavior#updateAjaxAttributes() and use
attributes.getExtraDynamicParameters().add("return
myJsFunctionThatReturnsJSONObject()")
myJsFunctionThatReturnsJSONObject is a function which you should implement
and make visible in the DOM.

Then in AjaxFormComponentUpdatingBehavior#onUpdate() you can use
getRequest().getRequestParameters() to read the values.


>
>
> On Mon, Feb 11, 2019 at 3:12 PM Ernesto Reinaldo Barreiro <
> [hidden email]> wrote:
>
> > create an smart LDM that goes to database only once and after that keeps
> > value?
> >
>