Dear Volunteers,
Please review the updated proposal for spec issue 1060 - Clear Input Values. Proposal is also attached as a text file.
SECTION: Introduction
ACTION: Please read this for background
EditableValueHolders that subclass UIInput save their input as the local
value during the process validations phase (this is saved as part of the
view state). The local value is later to be used to update the model
during the update model phase, and then it is cleared. However, when
validation fails, the component's local value is not cleared. In many
cases, this is exactly correct because we want to allow the user to
correct their mistake, and having the invalid value there as a reference
is helpful. Sometimes, this is not the desired behavior, though. The
page author cannot reset the value of the component by updating the
model values since the component uses the local value instead of
resolving the model values.
Sample scenario is as follows:
<h:form>
<h:messages />
<h:inputText id="firstname" value="#{bean.firstname}" required="true"/>
<h:inputText id="surname" value="#{bean.surname}" required="true"/>
<h:commandButton value="Ajax Save">
<f:ajax render="@form" execute="@form"/>
</h:commandButton>
<h:commandButton value="Non-Ajax Save" />
<h:commandButton value="Ajax Reset" actionListener="#{bean.reset}">
<f:ajax render="@form" execute="@this"/>
</h:commandButton>
<h:commandButton value="Non-Ajax Reset" actionListener="#{bean.reset}" immediate="true"/>
</h:form>
@ManagedBean
public class Bean {
private String firstname, surname;
//getter-setter
public void reset() {
firstname = null;
surname = null;
}
}
Steps to reproduce:
- Click the ajax save or non-ajax save without filling input fields to
get a validation error
- Click reset or non-ajax buttons, although reset method is executed on
bean, input components still show old value as they retrieve it from the
state.
SECTION: Known Solutions
ACTION: Please add if you are aware of any other solution
PrimeFaces
Provides a resetInput tag and a programmatic way, uses a tree visitor.
http://www.primefaces.org/showcase-labs/ui/resetInput.jsf
PrimeFaces Extensions
A resetInput tag and uses a preRenderView event to reset.
http://fractalsoft.net/primeext-showcase-mojarra/views/resetInput.jsf
MyFaces Trinidad
An action listener.
http://myfaces.apache.org/trinidad/trinidad-api/tagdoc/tr_resetActionListener.html
Omnifaces
An action listener/phase listener for ajax cases.
http://showcase-omnifaces.rhcloud.com/showcase/eventlisteners/ResetInputAjaxActionListener.xhtml
SECTION: Proposed Solution
ACTION: Please read this section and comment for feedback.
resetInput attribute in f:ajax
This part fixes the case for ajax requests. Most of the time,
page author would like to reset what is being updated just like
in Ajax Reset button in the sample code. If f:ajax resets the
components to update by going through
PartialViewContext.getRenderIds() component values will be reset
and model values will be used to display. Sample;
<h:commandButton value="Ajax Reset">
<f:ajax render="@form" execute="@this" resetInput="true|false"/>
</h:commandButton>
For backward compatibility, default value of the resetInput
attribute should be false. I know we don't want to add another
context-param but consider javax.faces.RESET_INPUT (false by
default) to globally override the resetInput attribute
setting. Still page authors can override the global setting per
component.
Even though this functionality is integrated with f:ajax, the
approach for resetting EditableValueHolders might be similar to
to the PrimeFaces Extension solution.
Modifications Required
- Modify f:ajax to describe resetInput attribute
- Modify jsf.js request to describe resetInput option
and what it is called like
javax.faces.partial.resetInput
- Modify partialViewContext to have a isResetInput()
which describes how to get the value from the incoming
request
- Modify spec section render response partial processing
2.2.6.1 to describe how to ask
partialviewcontext.isResetInput() and if so to get the
value of renderIds and call UIViewRoot.resetInput
passing that value.
ResetInput Tag
This tag goes in core namespace named <f:resetInput /> to cover
non-ajax requests. This is the solution used in PrimeFaces and
MyFaces Trinidad.
<h:commandButton value="Non-Ajax Reset" immediate="true">
<f:resetInput render="firstname surname or an ancestor" />
</h:commandButton>
Modifications Required
- Define a new tagHandler called f:resetInput with a render
attribute that is the same as in ajax case.
- And then a "for" attribute for the purpose of composite
components. (Similar to all of the other attached object
handlers)
- This tag handler causes an action listener to get attached to
the component and this particular action listener calls
UIViewRoot.reset with the values retrieved from the render
attribute.
Programmatic API
Programmatic API is provided for flexibility in case page authors
would like to decide when to reset. It is different than f:ajax
since it brings flexibility for conditional reset calls. This API is
used by the ResetInput Tag described in previous section.
UIViewRoot.resetValues(String clientIds as varargs)
The implementation uses a TreeVisitor with a ResetInputVisitCallback
and this callback checks if the component is a en
EditableValueHolder and if so calls resetValue().
Regards,
Cagatay Civici
PrimeFaces Lead
JSF EG Member
Prime Teknoloji
www.prime.com.tr
SECTION: Introduction
ACTION: Please read this for background
EditableValueHolders that subclass UIInput save their input as the local
value during the process validations phase (this is saved as part of the
view state). The local value is later to be used to update the model
during the update model phase, and then it is cleared. However, when
validation fails, the component's local value is not cleared. In many
cases, this is exactly correct because we want to allow the user to
correct their mistake, and having the invalid value there as a reference
is helpful. Sometimes, this is not the desired behavior, though. The
page author cannot reset the value of the component by updating the
model values since the component uses the local value instead of
resolving the model values.
Sample scenario is as follows:
<h:form>
<h:messages />
<h:inputText id="firstname" value="#{bean.firstname}" required="true"/>
<h:inputText id="surname" value="#{bean.surname}" required="true"/>
<h:commandButton value="Ajax Save">
<f:ajax render="@form" execute="@form"/>
</h:commandButton>
<h:commandButton value="Non-Ajax Save" />
<h:commandButton value="Ajax Reset" actionListener="#{bean.reset}">
<f:ajax render="@form" execute="@this"/>
</h:commandButton>
<h:commandButton value="Non-Ajax Reset" actionListener="#{bean.reset}" immediate="true"/>
</h:form>
@ManagedBean
public class Bean {
private String firstname, surname;
//getter-setter
public void reset() {
firstname = null;
surname = null;
}
}
Steps to reproduce:
- Click the ajax save or non-ajax save without filling input fields to
get a validation error
- Click reset or non-ajax buttons, although reset method is executed on
bean, input components still show old value as they retrieve it from the
state.
SECTION: Known Solutions
ACTION: Please add if you are aware of any other solution
PrimeFaces
Provides a resetInput tag and a programmatic way, uses a tree visitor.
http://www.primefaces.org/showcase-labs/ui/resetInput.jsf
PrimeFaces Extensions
A resetInput tag and uses a preRenderView event to reset.
http://fractalsoft.net/primeext-showcase-mojarra/views/resetInput.jsf
MyFaces Trinidad
An action listener.
http://myfaces.apache.org/trinidad/trinidad-api/tagdoc/tr_resetActionListener.html
Omnifaces
An action listener/phase listener for ajax cases.
http://showcase-omnifaces.rhcloud.com/showcase/eventlisteners/ResetInputAjaxActionListener.xhtml
SECTION: Proposed Solution
ACTION: Please read this section and comment for feedback.
resetInput attribute in f:ajax
This part fixes the case for ajax requests. Most of the time,
page author would like to reset what is being updated just like
in Ajax Reset button in the sample code. If f:ajax resets the
components to update by going through
PartialViewContext.getRenderIds() component values will be reset
and model values will be used to display. Sample;
<h:commandButton value="Ajax Reset">
<f:ajax render="@form" execute="@this" resetInput="true|false"/>
</h:commandButton>
For backward compatibility, default value of the resetInput
attribute should be false. I know we don't want to add another
context-param but consider javax.faces.RESET_INPUT (false by
default) to globally override the resetInput attribute
setting. Still page authors can override the global setting per
component.
Even though this functionality is integrated with f:ajax, the
approach for resetting EditableValueHolders might be similar to
to the PrimeFaces Extension solution.
Modifications Required
- Modify f:ajax to describe resetInput attribute
- Modify jsf.js request to describe resetInput option
and what it is called like
javax.faces.partial.resetInput
- Modify partialViewContext to have a isResetInput()
which describes how to get the value from the incoming
request
- Modify spec section render response partial processing
2.2.6.1 to describe how to ask
partialviewcontext.isResetInput() and if so to get the
value of renderIds and call UIViewRoot.resetInput
passing that value.
ResetInput Tag
This tag goes in core namespace named <f:resetInput /> to cover
non-ajax requests. This is the solution used in PrimeFaces and
MyFaces Trinidad.
<h:commandButton value="Non-Ajax Reset" immediate="true">
<f:resetInput render="firstname surname or an ancestor" />
</h:commandButton>
Modifications Required
- Define a new tagHandler called f:resetInput with a render
attribute that is the same as in ajax case.
- And then a "for" attribute for the purpose of composite
components. (Similar to all of the other attached object
handlers)
- This tag handler causes an action listener to get attached to
the component and this particular action listener calls
UIViewRoot.reset with the values retrieved from the render
attribute.
Programmatic API
Programmatic API is provided for flexibility in case page authors
would like to decide when to reset. It is different than f:ajax
since it brings flexibility for conditional reset calls. This API is
used by the ResetInput Tag described in previous section.
UIViewRoot.resetValues(String clientIds as varargs)
The implementation uses a TreeVisitor with a ResetInputVisitCallback
and this callback checks if the component is a en
EditableValueHolder and if so calls resetValue().