users@javaserverfaces-spec-public.java.net

[jsr344-experts mirror] [jsr344-experts] [1129-ClearInputValues] Resume Discussion

From: Edward Burns <edward.burns_at_oracle.com>
Date: Fri, 3 Aug 2012 12:45:05 -0700

Hello Experts,

Sorry for letting this one languish for so long. For a while it looked
like someone was going to step up and drive it all the way to a concrete
proposal, but the effort stalled.

This is my attempt at resuming work on it, starting by filing a proper
spec issue (related to but different from 1060).

>>>>> On Thu, 2 Jun 2011 21:34:33 +0300, Cagatay Civici <cagatay.civici_at_gmail.com> said:

CC> I'd like to discuss something I've been thinking about lately. How to
CC> clear forms easily when validation fails?

See <http://java.net/projects/javaserverfaces-spec-public/lists/jsr344-experts/archive/2011-06/message/0>

[...]

CC> But I mean shouldn't this work as expected?

CC> If at processValidations phase, local value is not stored in state, I
CC> think that will make the code above work, but I'm not sure if there will
CC> be any side effects. Does anyone know why converted local value is kept
CC> at state by calling setValue().

You are right to be concerned about side effects. This stuff is from
JSF 1.0. We should only dare to change it with great care, and with
full knowledge that we might be breaking things, and take necessary
precautions about doing so.

CC> Both mojarra and myfaces keeps the value at state and I cannot find
CC> anything regarding this in spec, please point me if I'm wrong.

>>>>> On Fri, 10 Jun 2011 15:11:52 -0400, Andy Schwartz <andy.schwartz_at_oracle.com> said:

AS> Isn't this done simply because we need some place to store the converted
AS> value until the update model phase?

The "submittedValue" property is the reason the value is kept "at state".

Section "Apply Request Values Phase" (Section number 2.5.1.1 in the
latest JSF 2.2 draft of the PDF) says, "The Renderer takes the value
from the request and passes it to the setSubmittedValue() of the
component".

Later, section "Executing Validation" (Section number 2.5.1.3) says, "If
any validation errors occur, they are dealt with as described in the
javadocs for Validator.validate() [1]. The converted value is pushed
into the component's setValue() method."

Note that the spec for Validator.validate() requires a
ValidatorException be thrown if validation fails, which causes the call
to setValue() to *not* happen. *BUT* the value still remains in the
component (as you observe) because of the call to setSubmittedValue().
If you look in the implementation code for UIInput.validate() you see a
call to setSubmittedValue(null) which will be called if validation does
not fail. You might ask, "where in the spec does it require a call to
setSubmittedValue(null)?" The spec for UIInput.validate() says "reset
the submitted value to null". I've added text that says, "with a call
to setSubmittedValue(null)."

AS> Looks like this is covered in the javadoc for UIInput [1]:

  By default, during the Process Validators phase of the request
  processing lifecycle, the submitted value will be converted to a
  typesafe object, and, if validation succeeds, stored as a local value
  using setValue().

Yes, that too, and we wanted to make it possible to have the invalid
value still there in the field, but *not* in the model, as a cue to the
user as to how to correct the value.

AS> I agree with you that the current state of affairs is rather
AS> confusing/difficult, so definitely open to doing something here. One
AS> possible way to go is to expose a listener along the lines of Trindiad's
AS> tr:resetActionListener [2].

AS> FWIW, I believe Trinidad constrains the reset to the nearest ancestor
AS> tr:subform.

This seems reasonable. But because ADF does not use h:form, I think
we'd have to change that rule to be the nearest ancestor NamingContainer.

CC> Yes that's right but setValue places the value in state, so it will
CC> be restored and used in rendering even the users want to use the
CC> model value to clear it. Instead of making it stateful, if local
CC> value is set in component instance, that could solve this issue, but
CC> I'm not sure about if there will be any side effects.

>>>>> On Wed, 15 Jun 2011 13:59:02 -0400, Andy Schwartz <andy.schwartz_at_oracle.com> said:

AS> Aside from the "reset" use case, another reason that this question might
AS> be worth examining more closely: if we don't need to state save the
AS> value attribute, it would be nice to remove this overhead from/reduce
AS> the size of our partial state saving state.

First, let's set the terms straight. The "submittedValue" property is
*not* saved into the state. The local value property *is* saved into
the state, but we have elaborate logic to cover when the value should be
cleared if the component instance has a ValueExpression for its value.

Perhaps we should not include the value in the state if the component
has a ValueExpression for the value. Otherwise, it *must* be stored in
the state, because it is not stored anywhere else. Note that in the
case of a validation error, the invalid value will be conveyed in the
rendering of the component, so it doesn't need to be in the state.

>>>>> On Fri, 6 Jul 2012 15:06:14 -0400, Kito Mann <kito.mann_at_virtua.com> said:

KM> I just ran into this issue with a client. What's the status? Is
KM> http://java.net/jira/browse/JAVASERVERFACES_SPEC_PUBLIC-1060 the issue of
KM> reference?

>>>>> On Mon, 16 Jul 2012 23:45:34 +0300, Catay Civici <cagatay.civici_at_gmail.com> said:

CC> Almost every day, I see a reference to this issue in PrimeFaces
CC> forum and stackoverflow.

>>>>> On Mon, 16 Jul 2012 17:08:14 -0400, Kito Mann <kito.mann_at_virtua.com> said:

KM> I'm working on this literally right now now for a client. It's a little
KM> more nuanced than the OmniFaces solution, because sometimes you want to
KM> reset the values for an Ajax request, and sometimes you don't. Regardless,
KM> there needs to be a solution that's integrated with <f:ajax> behavior,
KM> similar to what OmniFaces is doing or the <pe:resetInput> component from
KM> PrimeFaces-Extensions (all of these are referenced in the issue tracker).

Here is the most recent technical work on the thread.

>>>>> On Thu, 15 Mar 2012 13:34:20 -0500, Leonardo Uribe <lu4242_at_gmail.com> said:

LU> Hi Catay
LU> I think this is another use case where the evidence suggest we need a
LU> way to calculate quickly a "search expression" for a real component
LU> instance, like in:

LU> [jsr344-experts] Referencing composite component attributes in child
LU> components outside of a tree traversal

You are correct, a generalized mechanism like you suggest would be
applicable here, but I think we need a more targeted solution.

I think Andy's tr:resetActionListener is the ticket. Should we move
forward with that?

Thanks,

Ed

[1] https://maven.java.net/service/local/repositories/releases/archive/javax/faces/javax.faces-api/2.0/javax.faces-api-2.0-javadoc.jar/!/javadocs/javax/faces/validator/Validator.html#validate(javax.faces.context.FacesContext,%20javax.faces.component.UIComponent,%20java.lang.Object)

[2] http://myfaces.apache.org/trinidad/trinidad-api/tagdoc/tr_resetActionListener.html

-- 
| edward.burns_at_oracle.com | office: +1 407 458 0017
| homepage:               | http://ridingthecrest.com/