[richfaces-issues] [JBoss JIRA] Commented: (RF-11090) rich:collapsibleSubTable cannot be nested

Val Blant (JIRA) jira-events at lists.jboss.org
Wed Jul 20 22:25:23 EDT 2011


    [ https://issues.jboss.org/browse/RF-11090?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=12615556#comment-12615556 ] 

Val Blant commented on RF-11090:
--------------------------------

Daniel, I do have 3 levels of _collapsibleSubTable_ nesting, but I avoided the problem you are having by not using the _collapsibleSubTableToggler_ (b/c it doesn't work). Instead, I made my own composite component for toggling the sub-tables, which was much easier than fixing the renderer code.

If you are willing to settle for ajax refreshing the top-level dataTable on each collapse/expand operation, then you can do something similar to my solution.

{code}
	<rich:dataTable id="performanceIndicatorsTable" value="#{registeredBackingBean.thematicAreas}" var="thematicArea">
			
		<rich:column>
			<agr-comp:toggleTwistie 
				action="#{registeredBackingBean.toggleRenderedRowAction}" 
				openCondition="#{registeredBackingBean.renderThematicAreaRow}" 
				render="performanceIndicatorsTable" />
			<h:outputText value="#{thematicArea.thematicAreaNumber}"/>
		</rich:column>
			
		... more columns here ...
		
		<rich:collapsibleSubTable expanded="#{registeredBackingBean.renderThematicAreaRow}" value="#{thematicArea.programs}" var="designatedProgram">
					
			<rich:column>
				<agr-comp:toggleTwistie 
					action="#{registeredBackingBean.toggleRenderedProgramRowAction(designatedProgram)}" 
					openCondition="#{registeredBackingBean.getRenderProgramRow(designatedProgram)}" 
					render="performanceIndicatorsTable" />
				<h:outputText value="#{designatedProgram.programNum}" />
			</rich:column>		
			
			<rich:collapsibleSubTable expanded="#{registeredBackingBean.getRenderProgramRow(designatedProgram)}" value="#{designatedProgram.performanceIndicators}" var="performanceIndicator">
					   
				<rich:column>
					<agr-comp:toggleTwistie 
						action="#{registeredBackingBean.toggleRenderedIndictorRowAction(performanceIndicator)}" 
						openCondition="#{registeredBackingBean.getRenderIndicatorRow(performanceIndicator)}" 
						render="performanceIndicatorsTable" />
				</rich:column>
				
				... etc ...
				
			</rich:collapsibleSubTable>
		</rich:collapsibleSubTable>
	</rich:dataTable>

{code}

{code:title=toggleTwistie.xhtml}
<composite:interface>
	<composite:attribute name="openCondition" required="true" />
	<composite:attribute name="closedCondition" default="#{not cc.attrs.openCondition}" />
	<composite:attribute name="render" required="true" />
	<composite:attribute name="execute" default="@region" />
	<composite:attribute name="action" 
		method-signature="void action()" 
		required="true" />
</composite:interface>

<composite:implementation>
 
	<agr-comp:closedTwistie 
		render="#{cc.attrs.render}"
		action="#{cc.attrs.action}" 
		renderTwistie="#{cc.attrs.closedCondition}" />
	<agr-comp:openTwistie 
		render="#{cc.attrs.render}"
		action="#{cc.attrs.action}" 
		renderTwistie="#{cc.attrs.openCondition}" />
		
</composite:implementation>

{code}

{code:title=closedTwistie.xhtml}
<composite:interface>
	<composite:attribute name="render" required="true" />
	<composite:attribute name="renderTwistie" default="true" />
	<composite:attribute name="execute" default="@region" />
	<composite:attribute name="action" 
		method-signature="void action()" 
		targets="closedTwistieLink"
		required="true" />
</composite:interface>

<composite:implementation>
	<a4j:commandButton id="closedTwistieLink" 
		image="/images/down1.gif" 
		rendered="#{cc.attrs.renderTwistie}"
		render="#{cc.attrs.render}" 
		execute="#{cc.attrs.execute}"
		immediate="true"
		limitRender="true" 
		alt='#{msgs["button.label.close"]}'/>
</composite:implementation>
{code}

{code:title=openTwistie.xhtml}
<composite:interface>
	<composite:attribute name="render" required="true" />
	<composite:attribute name="renderTwistie" default="true" />
	<composite:attribute name="execute" default="@region" />
	<composite:attribute name="action" 
		method-signature="void action()" 
		targets="openTwistieLink"
		required="true" />
</composite:interface>

<composite:implementation>
	<a4j:commandButton id="openTwistieLink" 
		image="/images/down.gif" 
		rendered="#{cc.attrs.renderTwistie}"
		render="#{cc.attrs.render}" 
		execute="#{cc.attrs.execute}"
		immediate="true"
		limitRender="true" 
		alt='#{msgs["button.label.close"]}'/>
</composite:implementation>
{code}

I know it's messy, but I plan to switch to _collapsibleSubTableToggler_ in 4.1.0.Final once it comes out.

> rich:collapsibleSubTable cannot be nested
> -----------------------------------------
>
>                 Key: RF-11090
>                 URL: https://issues.jboss.org/browse/RF-11090
>             Project: RichFaces
>          Issue Type: Bug
>      Security Level: Public(Everyone can see) 
>          Components: component-tables
>    Affects Versions: 4.0.0.Final
>            Reporter: Val Blant
>             Fix For: 4.1.0.Final
>
>
> When _<rich:collapsibleSubTable />_ s are nested, the following error occurs:
> {quote}
> This page contains the following errors:
> error on line 202 at column 74: Opening and ending tag mismatch: tbody line 0 and tr
> Below is a rendering of the page up to the first error.
> {quote}
> The page is rendered up to the nested _<rich:collapsibleSubTable />_.
> This error happens b/c nested sub tables render an extra _</tr>_ element after the nested subtable row.
> I was able to work around the problem by making a small tweak to _CollapsibleSubTableRenderer_. The lines I added or changes are marked with *"// fix line"* comment.
> {code:title=FixedCollapsibleSubTableRenderer.java|borderStyle=solid}
> /**
>  * Allows nested subTables to be rendered properly
>  */
> @ResourceDependencies({
>     @ResourceDependency(name = "jquery.js"),
>     @ResourceDependency(name = "richfaces.js"),
>     @ResourceDependency(library="org.richfaces", name = "collapsible-subtable.ecss"),
>     @ResourceDependency(library="org.richfaces", name = "collapsible-subtable.js")
> })
> public class FixedCollapsibleSubTableRenderer extends CollapsibleSubTableRenderer {
> 	
> 	@Override
> 	public void encodeRow(ResponseWriter writer, FacesContext facesContext, RowHolderBase holder) throws IOException {
>         RowHolder rowHolder = (RowHolder)holder;
>         Row row = rowHolder.getRow();
>         putRowStylesIntoContext(facesContext, rowHolder);    
>         rowHolder.setRowStart(true);
>         Iterator<UIComponent> components = row.columns();
>         if (rowHolder.isUpdatePartial()) {
>             partialStart(facesContext,((AbstractCollapsibleSubTable) row).getRelativeClientId(facesContext) + ":b");
>         }
>         
>         int columnNumber = 0;
>         boolean isSubtable = false; // fix line
>         while (components.hasNext()) {
>             UIComponent component = components.next();
>             if(component.isRendered()) {
>                 if(component instanceof UIColumn ) {
>                     component.getAttributes().put(COLUMN_CLASS, getColumnClass(rowHolder, columnNumber));
>                     encodeColumn(facesContext, writer, (UIColumn)component , rowHolder);
>                     columnNumber++;
>                 } else if (component instanceof AbstractCollapsibleSubTable) {
>                     if(component.isRendered()) {
>                     	isSubtable = true; // fix line
>                         encodeRowEnd(writer);
>                     }
>                     
>                     if ( ((AbstractCollapsibleSubTable) component).isExpanded() ) {
> 	                    component.encodeAll(facesContext);
>                     }
>                     rowHolder.setRowStart(true);
>                 }
>             }    
>         }
>         if ( !isSubtable) encodeRowEnd(writer); // fix line
>         if (rowHolder.isUpdatePartial()) {
>             partialEnd(facesContext);
>         }
> 	}
> }
> {code}
> This renderer needs to be registered in _faces-config.xml_:
> {code}
> <render-kit>
>    <renderer>
>        <component-family>org.richfaces.Data</component-family>
>        <renderer-type>org.richfaces.CollapsibleSubTableRenderer</renderer-type>
>        <renderer-class>bla.FixedCollapsibleSubTableRenderer</renderer-class>
>    </renderer>
> </render-kit>
> {code}

--
This message is automatically generated by JIRA.
For more information on JIRA, see: http://www.atlassian.com/software/jira

        


More information about the richfaces-issues mailing list