I'm hitting a problem with auto-refreshing of tables using Trinidad 1.2.1,
facelets and JSF 1.2 (Sun RI). I've condensed the scenario down to a small test
case shown below. The summary is:
- I have a page which displays a table containing a collection of objects
- Each row of the table contains two command links - one to edit the row and
another to delete the row
- Both links pop-up a dialog with details of the row. Hitting the "save" button
on the dialog will either save the edit changes (if invoked from the edit link)
or delete the row (if invoked from the delete link).
- The table has a partialTriggers attribute which attempts to refresh the table
contents whenever a row is edited or deleted (i.e. partialTriggers contains the
ids of the edit and delete links)
- Everything appears to work fine apart from deletion of the last row in the
table whereby the table does not automatically refresh.
Is this a bug or am I doing something silly? Is there a better way to achieve
what I'm trying to do?
thanks in advance for any help.
Here's the source code:
widgetList.xhtml (page containing the
table):=============================<!DOCTYPE htmlPUBLIC "-//W3C//DTD XHTML 1.0
Strict//EN""http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"><tr:document
id="testForm" title="test form" xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:tr="http://myfaces.apache.org/trinidad"> <tr:panelBorderLayout>
<tr:form id="widgetListForm"> <tr:panelGroupLayout layout="vertical">
<tr:commandButton text="Create New Widget"
action="dialog:widgetDialog" useWindow="true" partialSubmit="true"
windowHeight="300" windowWidth="400" id="createWidgetCommand">
<tr:setActionListener from="#{widgetListBean.newWidgetBean}"
to="#{pageFlowScope.widgetBean}" /> <tr:setActionListener
from="#{'create'}" to="#{pageFlowScope.widgetBean.operation}" />
</tr:commandButton> <tr:commandButton text="Refresh Page"
id="refreshCommand"> </tr:commandButton> <tr:table
id="widgetTable" var="widgetBean" value="#{widgetListBean.widgetList}"
rowBandingInterval="1" partialTriggers="refreshCommand
createWidgetCommand widgetTable:editWidgetCommand
widgetTable:deleteWidgetCommand"> <tr:column> <f:facet
name="header"> <tr:outputText value="Widget Name" />
</f:facet> <tr:outputText value="#{widgetBean.name}" />
</tr:column> <tr:column> <f:facet name="header">
<tr:outputText value="Actions" /> </f:facet>
<tr:panelGroupLayout layout="horizontal"> <tr:commandLink
action="dialog:widgetDialog" useWindow="true"
partialSubmit="true" windowHeight="300" windowWidth="400"
id="editWidgetCommand" shortDesc="Edit the widget.">
<tr:image source="/skins/tn/images/ico_edit.gif" />
<tr:setActionListener from="#{'edit'}"
to="#{widgetBean.operation}" /> <tr:setActionListener
from="#{widgetBean}" to="#{pageFlowScope.widgetBean}" />
</tr:commandLink> <tr:commandLink
action="dialog:widgetDialog" useWindow="true"
partialSubmit="true" windowHeight="300" windowWidth="400"
id="deleteWidgetCommand" shortDesc="Delete the widget.">
<tr:image source="/skins/tn/images/ico_delete.gif" />
<tr:setActionListener from="#{'delete'}"
to="#{widgetBean.operation}" /> <tr:setActionListener
from="#{widgetBean}" to="#{pageFlowScope.widgetBean}" />
</tr:commandLink> </tr:panelGroupLayout>
</tr:column> </tr:table> </tr:panelGroupLayout> </tr:form>
</tr:panelBorderLayout></tr:document>widgetDialog.xhtml (the dialog that gets
popped up when edit or delete is
clicked):==========================================================<!DOCTYPE
htmlPUBLIC "-//W3C//DTD XHTML 1.0
Strict//EN""http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"><tr:document
id="testDialog" title="Dialog" xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:tr="http://myfaces.apache.org/trinidad"> <tr:form id="widgetDialogForm">
<tr:panelFormLayout id="widgetDialogForm" inlineStyle="width:20%">
<tr:inputText label="Widget Code"
value="#{pageFlowScope.widgetBean.name}" id="nameField" required="true"
showRequired="true" requiredMessageDetail="Widget name must be entered."
maximumLength="10"/> <f:facet name="footer">
<tr:panelButtonBar> <tr:commandButton id="saveCommand"
text="#{pageFlowScope.widgetBean.operation}"
action="#{pageFlowScope.widgetBean.commitAction}" /> <tr:commandButton
id="cancelCommand" text="Cancel"
action="#{pageFlowScope.widgetBean.cancelAction}" immediate="true"
/> </tr:panelButtonBar> </f:facet> </tr:panelFormLayout>
</tr:form></tr:document>WidgetList.java (backing bean for the main page -
manages the collection of
widgets)==========================================================public class
WidgetList{ public WidgetList() { _createInitialTestValues(); } public
List<Widget> getWidgetList() { return _widgetBeans; } public Widget
getNewWidgetBean() { Widget widget = new Widget(this, "");
widget.setOperation("create"); return widget; } private void
_createInitialTestValues() { _widgetBeans.add(new Widget(this, "w1"));
_widgetBeans.add(new Widget(this, "w2")); _widgetBeans.add(new Widget(this,
"w3")); } private List<Widget> _widgetBeans = new
ArrayList<Widget>();}Widget.java (backing bean for the individual
rows)=================================/** * Widget is a test bean */public
class Widget{ public Widget(WidgetList widgetList, String name) {
_widgetList = widgetList; _name = name; } public String getName() {
return _name; } public void setName(String name) { _name = name; }
public String getOperation() { return _operation; } public void
setOperation(String operation) { assert(operation.equals("edit") ||
operation.equals("create") || operation.equals("delete")); _operation =
operation; } public String commitAction() { if
(_operation.equals("create")) { _widgetList.getWidgetList().add(this);
} if (_operation.equals("delete")) {
_widgetList.getWidgetList().remove(this); } if
(_operation.equals("edit")) { // no change to owning collection }
TrinidadFacesUtils.endDialog(_widgetList); return null; } public String
cancelAction() { TrinidadFacesUtils.endDialog(this); return null; }
@Override public boolean equals(Object obj) { if (obj instanceof
Widget) { Widget w = (Widget) obj; return _name.equals(w._name);
} return false; } @Override public int hashCode() { return
_name.hashCode(); } @Override public String toString() { return _name;
} private String _name; private String _operation = "edit"; private
WidgetList _widgetList;}
_________________________________________________________________
Feel like a local wherever you go.
http://www.backofmyhand.com