jsr344-experts@javaserverfaces-spec-public.java.net

[jsr344-experts] [1060-Clear Input Values] Proposal

From: Çağatay Çivici <cagatay.civici_at_gmail.com>
Date: Tue, 4 Sep 2012 23:21:58 +0300

Dear experts,

This is the first draft of the proposal to provide an easy way for resetting editable value holders
that save their value at viewstate after validation failures. Proposal is created by me and Kito Mann.

Issue number in spec issue tracker is 1060;

http://java.net/jira/browse/JAVASERVERFACES_SPEC_PUBLIC-1060

Version 20120903

SECTION: Introduction

ACTION: Please read this for background on what this is all about.

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. 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.

 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 for="firstname surname or an ancestor of these components" />
        </h:commandButton>

Explain how the behavior of this tag is different than than <f:ajax>

 Programmatic API

    Programmatic API is provided for flexibility in case page authors would like to decide when to reset. There are
    two places where we can add this;

    FacesContext.reset(String clientId)
    FacesContext.reset(String clientIds as varargs)
    UIViewRoot.reset(String clientId)
    UIViewRoot.reset(String clientIds as varargs)

    The implementation uses a TreeVisitor with a ResetInputVisitCallback.

Regards,

Cagatay Civici
PrimeFaces Lead
JSF EG Member
Prime Teknoloji
www.prime.com.tr