Javascript to Fold/Unfold Hierarchical lists

Author Message

Fraser Hore

Tuesday 10 January 2006 12:12:24 pm

I find that the ability to fold/unfold (close/open) hierchical lists is a necessity for any long list. For example i'd like to have a multi-level list of tasks that where the user can drill down in the hierarchy. I've tried using the contentmenustructure and it works, but it seems overly complex for this purpose. I also couldn't figure out how to add attributes from the data_map after the object.name. For some reason the standard methods don't seem to be working.

Has anyone created a generic fold/unfold javascript and template combination that could be used to easily create foldable lists?

Idealy there is a template that has a fetch tree statement at the beginning which can be modified for individual needs (e.g. starting node, filters, etc.) and then the children are displayed as a fold/unfoldable hierarchical list using javascript. The basic template could just display the name of the object (linked to the object), but make it really easy to add additional attributes (not linked to the object) by adding them after the name (not linked to the object) in a <span></span>.

I've been able to generate this functionality using only template code (code below, just for fun) but it's slow and awkward. I don't know javascript so it would be great if someone has already done something like this.

Cheers,

Fraser

Fold/Unfold in Template Code:

{*Check if open nodes is set in the view parameters.  If not, do nothing. If yes, create an array of open nodes  assigned to the $open_nodes variable. If there is a close node view parameter set, don't include that node in the $open_nodes array*}

{def $vp_open_nodes=$view_parameters.open_nodes}
{def $vp_close_node=$view_parameters.close_node}
{def $open_nodes=concat("", $node.node_id)}

{def $items=fetch('content','tree', 
			hash('parent_node_id', $node.node_id,
			'class_filter_type', 'include',
			'class_filter_array', array('activity')))}
{if $vp_open_nodes|null()}
{else}
{foreach $items as $item}
     {if $vp_open_nodes|contains($item.node_id)}
          {if $vp_close_node|null()}
               {set $open_nodes=$open_nodes|append(",", $item.node_id)}
          {else}
               {if $vp_close_node|contains($item.node_id)}
               {else}
                    {set $open_nodes=$open_nodes|append(",", $item.node_id)}
               {/if}
          {/if}
     {/if}
{/foreach}
{/if}

{*Loop through the items printing all items that are in open folders*}
<div class="content-view-children">
{def $last_node=fetch( 'content', 'node', hash('node_id',   $node.node_id))}
{def $nodes_shown=array($node.node_id)}
{foreach $items as $item max 1}
<table cellspacing="5" width="100%">
	<tr>
		<th>Workstream/Activity</th>
		{def $content_object_attributes=$item.contentobject_version_object.contentobject_attributes}
		{foreach $content_object_attributes as $content_object_attribute offset 1}
			<th valign=top>
      			<label>{$content_object_attribute.contentclass_attribute.name|wash}</label>
			</th>
		{/foreach}
		<th>&nbsp;</th>
		<th>&nbsp;</th>
	</tr>
{/foreach}
{foreach $items as $item}
{def $content_object_attributes=$item.contentobject_version_object.contentobject_attributes}
{def $indent=sub( $item.depth, $node.depth)}
{set $indent=sub( $indent, 1)}
{set $indent=mul( $indent, 10)}

{if $nodes_shown|contains($item.parent_node_id)}
	{if $open_nodes|contains($item.parent_node_id)}
		{if $open_nodes|contains($item.node_id)}
	<tr>
		<td valign=top style="padding-left: {$indent}px">
			<span><a href="{$node.url_alias|ezurl(no)}/(open_nodes)/{$open_nodes}/(close_node)/{$item.node_id}"><img src={"folder_open.png"|ezimage} alt="" /></a></span>
			<span><a href={$node.url_alias|ezurl}>{$item.name|wash()}</a></span>
		</td>
		{foreach $content_object_attributes as $content_object_attribute offset 1}
		<td valign=top>
    			{attribute_view_gui attribute=$content_object_attribute}
		</td>
		{/foreach}
		<td>
			{*Add a button to edit the item*}
			{section show=$item.object.can_edit}
				<form method="post" action={"content/action/"|ezurl}>
			      	<input class="button" type="submit" name="EditButton" value="{'Edit'|i18n('design/standard/node/view')}" />
        				<input type="hidden" name="ContentObjectID" value="{$item.object.id}" />
				</form>
			{/section}
		</td>
		<td>
   		 	{*Add a button to add a new class item*}
   			<form method="post" action={"content/action/"|ezurl}>
       			<input class="button" type="submit" name="NewButton" value="New" />
        			<input type="hidden" name="ClassIdentifier" value="{$item.class_identifier}" />
        			<input type="hidden" name="NodeID" value="{$item.node_id}" />
   			</form>
		</td> 
	</tr>
		{else}
	<tr>
		<td valign=top style="padding-left: {$indent}px">
			<span><a href="{$node.url_alias|ezurl(no)}/(open_nodes)/{$open_nodes},{$item.node_id}"><img src={"folder_closed.png"|ezimage} alt="" /></a></span>
			<span><a href={$node.url_alias|ezurl}>{$item.name|wash()}</a></span>
		</td>
		{foreach $content_object_attributes as $content_object_attribute offset 1}
		<td valign=top>
    			{attribute_view_gui attribute=$content_object_attribute}
		</td>
		{/foreach}
		<td>
			{*Add a button to edit the item*}
			{section show=$item.object.can_edit}
				<form method="post" action={"content/action/"|ezurl}>
			      	<input class="button" type="submit" name="EditButton" value="{'Edit'|i18n('design/standard/node/view')}" />
        				<input type="hidden" name="ContentObjectID" value="{$item.object.id}" />
				</form>
			{/section}
		</td>
		<td>
   		 {*Add a button to add a new class item*}
   			<form method="post" action={"content/action/"|ezurl}>
       			<input class="button" type="submit" name="NewButton" value="New" />
        			<input type="hidden" name="ClassIdentifier" value="{$item.class_identifier}" />
        			<input type="hidden" name="NodeID" value="{$item.node_id}" />
   			</form>
		</td> 
	</tr>
		{/if}
                         {set $nodes_shown=$nodes_shown|append(",", $item.node_id)}
                    {/if}
               {/if}
{/foreach}
</table>
</div>

Xavier Dutoit

Wednesday 11 January 2006 4:05:31 am

Hi,

I've used a really nice js that is able to fold/unfold a hierarchic list (the way it should be, no table for that please ;)

http://www.gazingus.org/html/DOM-Scripted_Lists_Revisited.html

X+

http://www.sydesy.com

Fraser Hore

Saturday 14 January 2006 1:59:20 am

Thanks Xavier for the tip! This is exactly what i was looking for! I created a little extension so that it's really easy to include an expandable list in a template using an include. You can just define the root node and the style you want to use and then include the template to show the expandable list.

http://ez.no/community/contribs/hacks/expandablelist

Cheers,

Fraser

Xavier Dutoit

Saturday 14 January 2006 5:55:42 am

My pleasure.

X+

http://www.sydesy.com

Powered by eZ Publish™ CMS Open Source Web Content Management. Copyright © 1999-2014 eZ Systems AS (except where otherwise noted). All rights reserved.

eZ debug

Timing: Jan 20 2025 20:12:37
Script start
Timing: Jan 20 2025 20:12:37
Module start 'layout'
Timing: Jan 20 2025 20:12:37
Module start 'content'
Timing: Jan 20 2025 20:12:38
Module end 'content'
Timing: Jan 20 2025 20:12:38
Script end

Main resources:

Total runtime1.2734 sec
Peak memory usage4,096.0000 KB
Database Queries60

Timing points:

CheckpointStart (sec)Duration (sec)Memory at start (KB)Memory used (KB)
Script start 0.00000.0040 588.0469151.2266
Module start 'layout' 0.00400.0020 739.273436.6797
Module start 'content' 0.00601.2665 775.9531591.2031
Module end 'content' 1.27250.0008 1,367.156319.8125
Script end 1.2734  1,386.9688 

Time accumulators:

 Accumulator Duration (sec) Duration (%) Count Average (sec)
Ini load
Load cache0.00280.2213160.0002
Check MTime0.00120.0913160.0001
Mysql Total
Database connection0.00070.051810.0007
Mysqli_queries1.220695.8509600.0203
Looping result0.00080.0642580.0000
Template Total1.247898.020.6239
Template load0.00210.167120.0011
Template processing1.245697.821320.6228
Template load and register function0.00010.009710.0001
states
state_id_array0.00120.097810.0012
state_identifier_array0.00130.099220.0006
Override
Cache load0.00180.1423280.0001
Sytem overhead
Fetch class attribute can translate value0.00080.065820.0004
Fetch class attribute name0.00150.115160.0002
XML
Image XML parsing0.00100.081920.0005
class_abstraction
Instantiating content class attribute0.00000.001380.0000
General
dbfile0.00120.0904220.0001
String conversion0.00000.000440.0000
Note: percentages do not add up to 100% because some accumulators overlap

Templates used to render the page:

UsageRequested templateTemplateTemplate loadedEditOverride
1node/view/full.tplfull/forum_topic.tplextension/sevenx/design/simple/override/templates/full/forum_topic.tplEdit templateOverride template
4content/datatype/view/ezimage.tpl<No override>extension/sevenx/design/simple/templates/content/datatype/view/ezimage.tplEdit templateOverride template
4content/datatype/view/ezxmltext.tpl<No override>extension/community_design/design/suncana/templates/content/datatype/view/ezxmltext.tplEdit templateOverride template
4content/datatype/view/ezxmltags/paragraph.tpl<No override>extension/ezwebin/design/ezwebin/templates/content/datatype/view/ezxmltags/paragraph.tplEdit templateOverride template
1content/datatype/view/ezxmltags/literal.tpl<No override>extension/community/design/standard/templates/content/datatype/view/ezxmltags/literal.tplEdit templateOverride template
1print_pagelayout.tpl<No override>extension/community/design/community/templates/print_pagelayout.tplEdit templateOverride template
 Number of times templates used: 15
 Number of unique templates used: 6

Time used to render debug report: 0.0001 secs