Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to achieve nested conditional rendering without empty span tags from apex:outputPanel?

I am trying to generate clean XSL-FO from a VisualForce page. But the xml coming out of the VisualForce page is not valid due to the empty span tags that are being generated by nested apex:outputPanel tags (outer rendered=true, inner rendered=false). Here is a focused page that illustrates the problem:

<apex:page contentType="text/xml" cache="false" showHeader="false" sidebar="false">
    <root>
        There is no reason for a nested apex:outputpanel to generate a span tag like this:  

        <apex:outputPanel layout="none" rendered="true">
            <apex:outputPanel layout="none" rendered="false" />
        </apex:outputPanel>

        This breaks strict xml documents like XSL-FO.
    </root>        
</apex:page>

That page gives this xml output:

<root>
    There is no reason for a nested apex:outputpanel to generate a span tag like this:

    <span id="j_id0:j_id3" style="display: none;"></span>

    This breaks strict xml documents like XSL-FO.
</root>

Actually, I did find an obscure reason in the docs:

apex:outputPanel layout attribute - The layout style for the panel. Possible values include "block" (which generates an HTML div tag), "inline" (which generates an HTML span tag), and "none" (which does not generate an HTML tag). If not specified, this value defaults to "none". However, if layout is set to "none", for each child element with the rendered attribute set to "false", the outputPanel generates a span tag, with the ID of each child, and a style attribute set to "display:none". Thus, while the content is not visible, JavaScript can still access the elements through the DOM ID.

Sounds useful if my content type is html or javascript, but it's breaking my strict xml. So the question is: how can I achieve nested conditional rendering while avoiding the span tags?

like image 283
twamley Avatar asked May 15 '12 05:05

twamley


1 Answers

Switch both, or just the outer, to an apex:variable like this:

<apex:variable rendered="true" value="" var="tempOuter">
    <apex:outputPanel layout="none" rendered="false" />
</apex:variable>
like image 128
twamley Avatar answered Sep 21 '22 06:09

twamley