javascript - xsl expand and collapse after "N" child elements -
i have xml can has variable number of child elements.
 need way add expand / collapse feature when there more "n" number of child elements.
 example xml  
<?xml version="1.0"?> <testxml>     <n>test</n>     <ntlist>         <nt>             <nt1>nt1 test 1</nt1>             <nt2>nt2 test 1</nt2>         </nt>         <nt>             <nt1>nt1 test 2</nt1>             <nt2>nt2 test 2</nt2>         </nt>         <nt>             <nt1>nt1 test 3</nt1>             <nt2>nt2 test 3</nt2>         </nt>     </ntlist> </testxml>   so in example add expand / collapse if there more 2 "nt" inside "ntlist".
 
 think this close can't find way determine when add expand / collapse after "n" records has been reached.
 
 basic html output:  
n : test ntlist     nt (1)         nt1 : nt1 test 1         nt2 : nt2 test 1     nt (2)         nt1 : nt1 test 2         nt2 : nt2 test 2     nt (+more) <- link click expand 3rd nt.      
as have jquery tag think following solution work you. can determine nth record using position() in xsl:for-each loop. example n = 3:
xslt:
<?xml version="1.0" encoding="utf-8" ?> <xsl:transform xmlns:xsl="http://www.w3.org/1999/xsl/transform"       version="1.0"> <xsl:output method="html" doctype-public="xslt-compat"       omit-xml-declaration="yes" encoding="utf-8" indent="yes" />   <xsl:template match="testxml">     <ul>       <li>n : test<br/>ntlist         <xsl:for-each select="ntlist/nt">                  <ul>             <li>               <xsl:if test="position() >=3">                 <xsl:attribute name="class" select="'toggle'"/>               </xsl:if>               <xsl:value-of select="                if(position() < 3)                concat(local-name(),  ' (', position(),')')                else concat(local-name(),  ' (+more)')"/>                 <ul>                   <xsl:if test="position() >=3">                     <xsl:attribute name="class" select="'hidden'"/>                   </xsl:if>                   <xsl:for-each select="*">                     <li>                       <xsl:value-of select="."/>                     </li>                   </xsl:for-each>                 </ul>              </li>           </ul>         </xsl:for-each>       </li>     </ul>   </xsl:template> </xsl:transform>   when applied input xml produces ouput (relevant part):
<ul>    <li>n : test<br/>ntlist       <ul>          <li>nt (1)             <ul>                <li>nt1 test 1</li>                <li>nt2 test 1</li>             </ul>          </li>       </ul>       <ul>          <li>nt (2)             <ul>                <li>nt1 test 2</li>                <li>nt2 test 2</li>             </ul>          </li>       </ul>       <ul>          <li class="toggle">nt (+more)             <ul class="hidden">                <li>nt1 test 3</li>                <li>nt2 test 3</li>             </ul>          </li>       </ul>    </li> </ul>   following css hides lists have class hidden , removes bulletpoints list elements:
ul {   list-style-type:none; } .hidden {   display:none;) }   and following jquery:
$(".toggle").on("click", function () {   $(this).find("ul").slidetoggle(); });   will toggle hidden lists. added fiddle result.
for reference: position(), http://api.jquery.com/slidetoggle/
update: mentioned in comment, suggested approach not work op settings (visual studio) because of using if in select attribute , using select in xsl:attribute. following xslt generates same output using xsl:when statements instead. can't test if work in visual studio if not, can add comment new error.  
<?xml version="1.0" encoding="utf-8" ?> <xsl:transform xmlns:xsl="http://www.w3.org/1999/xsl/transform" version="1.0"> <xsl:output method="html" doctype-public="xslt-compat" omit-xml-declaration="yes" encoding="utf-8" indent="yes" />   <xsl:template match="testxml">     <ul>         <li>             n : test<br/>             ntlist             <xsl:for-each select="ntlist/nt">                 <ul>                     <li>                       <xsl:if test="position() >=3">                         <xsl:attribute name="class">toggle</xsl:attribute>                       </xsl:if>                       <xsl:choose>                         <xsl:when test="position() < 3">                           <xsl:value-of                                 select="concat(local-name(), ' (', position(),')')"/>                         </xsl:when>                         <xsl:otherwise>                           <xsl:value-of                                   select="concat(local-name(), ' (+more)')"/>                         </xsl:otherwise>                       </xsl:choose>                       <ul>                         <xsl:if test="position() >=3">                           <xsl:attribute name="class">hidden</xsl:attribute>                              </xsl:if>                         <xsl:for-each select="*">                           <li>                             <xsl:value-of select="."/>                           </li>                         </xsl:for-each>                       </ul>                     </li>                 </ul>             </xsl:for-each>         </li>     </ul>   </xsl:template> </xsl:transform>   update: mentioned in comment, overlooked change 2 select-statements in xsl:attribute. fixed adjusting e.g. <xsl:attribute name="class">hidden</xsl:attribute>. avoid potential issues in case of whitespace or linebreaks changed adding  <xsl:text> wrapper:  
<xsl:attribute name="class">   <xsl:text>hidden</xsl:text> </xsl:attribute>      
Comments
Post a Comment