[richfaces-issues] [JBoss JIRA] (RF-9443) switchable panels: It should be possible to iterate child panels using a4j:repeat component
Brian Leathem (JIRA)
jira-events at lists.jboss.org
Fri Sep 21 10:16:37 EDT 2012
[ https://issues.jboss.org/browse/RF-9443?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=12720673#comment-12720673 ]
Brian Leathem commented on RF-9443:
-----------------------------------
By far the simplest way to get this working for columns is to have the iterator use the visitor pattern to walk the children of the a4j:repeat. A naive implementation of this idea is as follows:
{code:title="DataTableColumnsIterator modified to walk UIRepeat"}
class DataTableColumnsIterator extends AbstractIterator<UIComponent> {
class VisitState {
int index = 0;
int repeaterIndex = -1;
UIComponent repeater;
UIComponent component;
boolean valid = false;
public void trackRepeater(UIComponent repeater) {
repeaterIndex = index;
this.repeater = repeater;
valid = true;
}
public void forgetRepeater() {
repeaterIndex = -1;
repeater = null;
valid = false;
}
}
private Iterator<UIComponent> childrenIterator;
private VisitState visitState;
private FacesContext context;
public DataTableColumnsIterator(UIComponent component) {
super();
visitState = new VisitState();
this.childrenIterator = component.getChildren().iterator();
context = FacesContext.getCurrentInstance();
}
@Override
protected UIComponent computeNext() {
while (childrenIterator.hasNext() || visitState.repeater != null) {
UIComponent child = visitState.repeater == null ? childrenIterator.next() : visitState.repeater;
if (child instanceof UIColumn || child instanceof Column) {
visitState.index++;
return child;
}
else if (child instanceof UIRepeat) {
final UIRepeat repeater = (UIRepeat) child;
if (! visitState.valid) {
visitState.trackRepeater(repeater);
}
try {
DataVisitor visitor = new DataVisitor() {
public DataVisitResult process(FacesContext context, Object rowKey, Object argument) {
repeater.setRowKey(context, rowKey);
if (repeater.isRowAvailable()) {
if (repeater.getChildCount() > 0) {
visitState.repeater = repeater;
int index = visitState.repeaterIndex + 1;
for (UIComponent child : repeater.getChildren()) {
if (index == visitState.index + 1) {
visitState.index++;
visitState.component = child;
return DataVisitResult.STOP;
}
index++;
}
visitState.forgetRepeater();
}
}
return DataVisitResult.CONTINUE;
}
};
repeater.walk(context, visitor, null);
} finally {
repeater.setRowKey(context, null);
}
if (visitState.component != null) {
UIComponent component = visitState.component;
visitState.component = null;
return component;
}
}
}
return endOfData();
}
}
{code}
the problem with the above approach, is the visit context is closed when the column object is returned. This means any attributes to be resolved that rely on the _rowKey_ (such as the _clientId_) will fail.
One way around this, is to have the above iterator keep the visit context alive until the iteration over the UIRepeat's children is complete. Further investigation is required.
> switchable panels: It should be possible to iterate child panels using a4j:repeat component
> -------------------------------------------------------------------------------------------
>
> Key: RF-9443
> URL: https://issues.jboss.org/browse/RF-9443
> Project: RichFaces
> Issue Type: Bug
> Security Level: Public(Everyone can see)
> Components: component-panels-layout-themes
> Affects Versions: 4.0.0.Milestone2
> Reporter: Ilya Shaikovsky
> Assignee: Brian Leathem
> Fix For: 4.3.0.Milestone2
>
>
> requirement present there - http://community.jboss.org/wiki/RichFaces4xswitchablepanels
> Alex, consider this issue to implementation only after all the new components tasks for M4. If will not fit - postpone to next one as it has workaround.
--
This message is automatically generated by JIRA.
If you think it was sent incorrectly, please contact your JIRA administrators
For more information on JIRA, see: http://www.atlassian.com/software/jira
More information about the richfaces-issues
mailing list