Details
-
Type:
Bug
-
Status: Closed
-
Priority:
Major
-
Resolution: Duplicate
-
Affects Version/s: 1.5.3
-
Fix Version/s: None
-
Component/s: ICE-Components
-
Labels:None
-
Environment:Windows XP / Tomcat 5.5.17
-
Support Case References:
-
Workaround Exists:Yes
-
Workaround Description:HideThe workaround is a hack. It involves putting an action listener on the Cancel button:
<ice:commandButton actionListener="#{PortalUserList.rowPanelGroupCancelButtonListener}" immediate="true" styleClass="portlet-form-button" value="#{DataTableMsgs.keyValues['Cancel']}"/>
Here is the listener:
public void rowPanelGroupCancelButtonListener(ActionEvent actionEvent)
{
this.rowPanelGroupVisible = false;
JSFUtils.clearSubmittedFormValues(JSFUtils.getForm(actionEvent.getComponent()));
}
And here is the clearSubmittedFormValues() static methods from my JSFUtils class:
/**
* This method (along with its private, recursive counterpart) is more or less a hack to try and fix a problem that
* manifests itself with ICEfaces and <ice:commandButton> components with immediate="true". The folks at ICEsoft
* need to make this be part of their partial-submit aspect of the JSF lifecycle.
*/
public static void clearSubmittedFormValues(UIForm uiForm)
{
clearSubittedFormValuesRecurse(uiForm);
}
private static void clearSubittedFormValuesRecurse(UIComponent uiComponent)
{
if (uiComponent instanceof UIInput)
{
UIInput uiInput = (UIInput) uiComponent;
uiInput.setSubmittedValue(null);
}
List childList = uiComponent.getChildren();
if (childList != null)
{
Iterator iterator = childList.iterator();
while (iterator.hasNext())
{
clearSubittedFormValuesRecurse((UIComponent) iterator.next());
}
}
}
ShowThe workaround is a hack. It involves putting an action listener on the Cancel button: <ice:commandButton actionListener="#{PortalUserList.rowPanelGroupCancelButtonListener}" immediate="true" styleClass="portlet-form-button" value="#{DataTableMsgs.keyValues['Cancel']}"/> Here is the listener: public void rowPanelGroupCancelButtonListener(ActionEvent actionEvent) { this.rowPanelGroupVisible = false; JSFUtils.clearSubmittedFormValues(JSFUtils.getForm(actionEvent.getComponent())); } And here is the clearSubmittedFormValues() static methods from my JSFUtils class: /** * This method (along with its private, recursive counterpart) is more or less a hack to try and fix a problem that * manifests itself with ICEfaces and <ice:commandButton> components with immediate="true". The folks at ICEsoft * need to make this be part of their partial-submit aspect of the JSF lifecycle. */ public static void clearSubmittedFormValues(UIForm uiForm) { clearSubittedFormValuesRecurse(uiForm); } private static void clearSubittedFormValuesRecurse(UIComponent uiComponent) { if (uiComponent instanceof UIInput) { UIInput uiInput = (UIInput) uiComponent; uiInput.setSubmittedValue(null); } List childList = uiComponent.getChildren(); if (childList != null) { Iterator iterator = childList.iterator(); while (iterator.hasNext()) { clearSubittedFormValuesRecurse((UIComponent) iterator.next()); } } }
Description
-
Hide
- ice-1343-standard.zip
- 1.77 MB
- Neil Griffin
-
- ice-1343-standard/index.jsp 0.7 kB
- ice-1343-standard/WEB-INF/.../MyBean.class 2 kB
- ice-1343-standard/.../faces-config.xml 0.4 kB
- ice-1343-standard/.../commons-beanutils.jar 184 kB
- ice-1343-standard/.../commons-collections.jar 558 kB
- ice-1343-standard/.../commons-digester.jar 137 kB
- ice-1343-standard/.../commons-logging.jar 52 kB
- ice-1343-standard/WEB-INF/.../jsf-api.jar 356 kB
- ice-1343-standard/WEB-INF/.../jsf-impl.jar 682 kB
- ice-1343-standard/WEB-INF/lib/jstl.jar 21 kB
- ice-1343-standard/WEB-INF/.../MyBean.java 0.8 kB
- ice-1343-standard/WEB-INF/web.xml 1.0 kB
Issue Links
- duplicates
-
ICE-1741 submittedValue of component remains stored during page navigation
-
- Closed
-
Activity
- All
- Comments
- History
- Activity
- Remote Attachments
- Subversion
Is it possible to get a fix for this in ICEfaces 1.6-final?
Thank you,
Neil Griffin
Liferay, Inc.
could you include the "getForm()" method from your JSFUtils class?
Yes, here it is, sorry:
public static UIForm getForm(UIComponent uiComponent)
{
while (uiComponent != null)
{
if (uiComponent instanceof UIForm)
uiComponent = uiComponent.getParent();
}
return ((UIForm) uiComponent);
}
Thanks for looking into fixing this!!
Please let me know if I can be of any help.
Neil Griffin
Liferay, Inc.
Sadly, I'm not an IceFaces developer, so I'm in the same boat as you are - hoping the IceFaces team will fix this soon!
Be sure to vote for this bug if you haven't already!
It seems that I found where the bug in our project is from. It is very very critical. When I set <ice:commandButton immediate="true" value="Cancel"/>, after clicking on the Cancel button, then click a Start button again, the previous value was always kept in its bean. I spent two days to find the bug, but I don't know where it was really from. Later, I reluctantly remove immediate="true", but in this way, we could not set some fields to required="true". I really hope this bug can be fixed in 1.7#DIV. Thank you so much, ICEfaces team.
Paraphrasing Neil:
An h:commandButton in in a non-ICEfaces environment, with immediate="true" will set the submittedValue's to null for all UIInputs in the same UIForm. But, ice:commandButton in an ICEfaces environment, with immediate="true", is not.
We should look at this from a partialSubmit, and a non-partialSubmit point of view.
Sheng Gu : If the submittedValues have passed validation, been set into the component value, and in the update model phase been set into the beans, then there's nothing that can be done. Unless you mean that the submittedValues stayed in the components, and were then pushed into the beans because of the Start button press. That is what we'll be fixing.
A test case is needed with h:commandButton. The test case can then be evaluated both with and without ICEfaces.
To Mark Collette: In our project, a user click on calendar schedule (MyFaces), then the calendar will pop up a popup panel with the clicked time. If the user click cancel button and click on another time, then the popup will get another the clicked time. However, if I set immediate=true, the popup always keep the first clicked time. Only after I set the immediate=false, then use can always get his clicked time on each click. But when setting immediate=false, the popup will validate each required field when use click Cancel, that is very bad. Thanks.
Sheng Gu: Ok, so do you have an ice:selectInputDate with renderAsPopup="true", or are you making your own popup panel display? Is the cancel button an actual commandButton, or the X button on the calendar popup? You're setting immediate="true" on this cancel commandButton, or on the selectInputDate?
Hi Mark, we did not use ice:selectInputDate with renderAsPopup="true" as a popup in our schedule (seven week day columns) page. We have our own popup panel display which shows the clicked time (date and time) as schedule start time, schedule title and schedule interval. There are two ice:commandButton buttons on the popup panel: one is submit button, the other is cancel button. If I set cancel button immediate="true", the schedule start time will always keep the first clicked time, even click cancel then click another time. Only I set cancel button immediate=false, then the schedule time can get lastest clicked time. Thank you.
For panelPopup users more suitable will be code below.
Use this when inputs and Cancel button is on the same panelGrid.
In my case I saw that original recurse function not work correct on panelPopup
and gives this log :
- getForm uicomponent com.icesoft.faces.component.ext.HtmlCommandButton@1866417
- getForm uicomponent com.icesoft.faces.component.UIXhtmlComponent@1386211:tag=[div]
- getForm uicomponent com.icesoft.faces.component.ext.HtmlPanelGrid@ac2d3c
- getForm uicomponent com.icesoft.faces.component.panelpopup.PanelPopup@1cdc190
- getForm uicomponent com.icesoft.faces.component.ext.HtmlForm@15ede11
- clearSubittedFormValuesRecurse class com.icesoft.faces.component.ext.HtmlForm
- clearSubittedFormValuesRecurse class com.icesoft.faces.component.panelpopup.PanelPopup
That means then ..PanelPopup don't get their childrens.
So I change UIForm to UIPanel and getting childrens and clearing state work correct
/**
- @see clearSubmittedFormValues
- @param uiComponent
*/
private static void clearSubittedFormValuesRecurse(UIComponent uiComponent)
{
System.out.println("clearSubittedFormValuesRecurse "+uiComponent);
if (uiComponent instanceof UIInput) { UIInput uiInput = (UIInput) uiComponent; uiInput.setSubmittedValue(null); System.out.println("clearSubittedFormValuesRecurse "+uiInput.getId()); }List<?> childList = uiComponent.getChildren();
if (childList != null)Unknown macro: { Iterator<?> iterator = childList.iterator(); while (iterator.hasNext()) { clearSubittedFormValuesRecurse((UIComponent) iterator.next()); } }}
/**
- Util for clearSubmittedFormValues
- @see clearSubmittedFormValues
- @param uiComponent
- @return
*/
public static /UIForm/UIPanel getForm(UIComponent uiComponent)
{
while (uiComponent != null)Unknown macro: { System.out.println("getForm uicomponent"+ uiComponent); if (uiComponent instanceof UIPanel /*UIForm*/) { break; } uiComponent = uiComponent.getParent(); }return (/(UIForm)/ (UIPanel) uiComponent);
}
Since there maybe panels and facets in a single form.
I suggested to change the work around as follows:
private static void clearSubittedFormValuesRecurse(UIComponent uiComponent)
{ UIInput uiInput = (UIInput) uiComponent; uiInput.setSubmittedValue(null); }{
if (uiComponent instanceof UIInput)
// Use getFacetsAndChildren to ensure all children in facets are scanned too.
{ clearSubittedFormValuesRecurse((UIComponent) childIterator.next()); }Iterator childIterator = uiComponent.getFacetsAndChildren();
if (childIterator != null)
{
while (childIterator.hasNext())
}
}