No, that is not the scenario (i have no immediate input component). The
scenario is a component that, during apply request value, (1st phase)
calls context.renderResponse().
JSF docs states about it:
"Signal the JavaServer faces implementation that, as soon as the current
phase of the request processing lifecycle has been completed, control
should be passed to the /Render Response/ phase, bypassing any phases
that have not been executed yet."
That does *not* mean there is an error and i such i see no reason for
all component making use of renderResponse() to generate an additionnal
FacesMessage, and to tell what "you clicked on Y so i showed you Y in
form" ?. An example of such scenario is changing the tab in a
tabbedpane, the tabbedpane component sees in request parameters that
user clicked on a tab, it changes it's internal state and ask for form
redisplay. The fact active tab change does certainly not mean the
datatable in same form but *outside* tabbedpane should reset it's state
to backing bean. I am quite sure the the specs of JSF mandates that
component redisplayed show back to user what he submitted.
My situation is as follow
<datatable>
<column>
<component X>
the component X need by design that it's state be changed by use of
specific form buttons, so when user click one of those buttons, it
changes it's state. And because just after component changed it's state
UIData resets it, i am stuck with a dead component (does not seem to
react). Note that i
1) first ensured it was due to datatable (work perfectly ouside of
datatable)
2) ensured it is due to the check on _isValidChilds (applied attached
patch locally to myfaces-api-1.1.5, works like a charm)
Note that it looks to me wrong to consider childs component are valid if
there were no error during validation and conversion. It is valid only
if there were no such errors *and* the validation / conversion occured.
(In my case, component X is a custom component that is an editor for a
array. So it need to create add/remove buttons that it uses during apply
request value, if that component is in a datatable it does not work)
Maybe dev- mailing list could be more appropriate for this discussion :/
En l'instant précis du 21/11/07 16:18, Simon Kitching s'exprimait en ces
termes:
Hi David,
Just to clarify, is this the scenario?
* You have a page with an immediate input component
* You also have a datatable with an input component in it
You enter data into the datatable input and submit. However during postback
processing the immediate input component that is NOT in the table fails
validation. The render phase therefore runs without pushing the table data into
the model.
And somehow the entered data in the datatable's component is being cleared?
The logic from the datatable class initially looks ok to me:
if (_isValidChilds && !hasErrorMessages(context))
There should be an error message present in the context (the one due to the
validation failure) so the stored state for the components within the datatable
should not be cleared.
Have you perhaps written a custom validator that fails for the immediate
component, but never registers an error message?
I think checking hasErrorMessages is a little bit of a hacky way of determining whether
validation has failed. But twiddling _isValidChilds is also ugly; surely that is meant to
reflect only the status of the child components within the datatable? If anything, I
would suggest replacing hasErrorMessages by a method called
"hasValidationPassed", which then could check a flag that can be twiddled
appropriately..
Cheers,
Simon
---- David Delbecq <[EMAIL PROTECTED]> schrieb:
Hello,
I tried to hunt a bug today and i want to know if this is expected
behaviour of datatable or a bug. Someone with deep knowledge of JSF
specs could answer me please?
A) If a JSF action is immediate (call to FacesContext.renderResponse()
durring apply request value phase), submitted values of "non immediate"
components are neither converted to localvalues, nor validated and
stored in model.
B) If a datatable has only valid childs and there is no error message,
during render response phase, it clears the datamodel and the rows saved
state
My problem is B, when no validation occured, B is assuming all childs
have sucessfully validated, which is *NOT* the case (validation phase
skipped). As a result, all input fields in datatable have their
submitted value reseted to null and, upon form redisplay, the fields are
back to backing bean values, whatever user had entered has been ignored.
My question are,
- in case this is the behaviour mandatored by JSF specs, is there a way
around it?
- if not, can we consider a bug of JSF?
extract from what i think is the cullprit code (UIData class):
/**
* Perform necessary actions when rendering of this component starts,
* before delegating to the inherited implementation which calls the
* associated renderer's encodeBegin method.
*/
public void encodeBegin(FacesContext context) throws IOException
{
_initialDescendantComponentState = null;
if (_isValidChilds && !hasErrorMessages(context))
{
// Clear the data model so that when rendering code calls
// getDataModel a fresh model is fetched from the backing
// bean via the value-binding.
_dataModelMap.clear();
// When the data model is cleared it is also necessary to
// clear the saved row state, as there is an implicit 1:1
// relation between objects in the _rowStates and the
// corresponding DataModel element.
_rowStates.clear();
}
super.encodeBegin(context);
}
solution could be to add, at the end of UIData.processDecodes(FacesContext):
// check if an immediate action forces the render response for
our data
if (context.getRenderResponse())
{
_isValidChilds = false; //validation phase will be skipped
}
another could be to default _isValidChilds to false until the begin of
processValidators()
any suggestion appreciated.
--
http://www.devlog.be (a belgian developer's logs)
--
David Delbecq
Institut Royal Météorologique
Ext:557
Index: src/main/java/javax/faces/component/UIData.java
===================================================================
--- src/main/java/javax/faces/component/UIData.java (revision 597066)
+++ src/main/java/javax/faces/component/UIData.java (working copy)
@@ -593,6 +593,11 @@
context.renderResponse();
throw e;
}
+ // check if an immediate action forces the render response for our data
+ if (context.getRenderResponse())
+ {
+ _isValidChilds = false; //validation phase will be skipped
+ }
}
public void processValidators(FacesContext context)