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