HTML Tree View with <ol> and <a href>

Eddie Corns eddie at holyrood.ed.ac.uk
Fri Jan 28 12:32:23 EST 2005


Gregor Horvath <g.horvath at gmx.at> writes:

>Hi,

>Before I reinvent the wheel I`d like to ask if someone has done this 
>before since I did not find an advice at Google.

>The goal is to create a dynamic Tree View in HTML.

>Say I have a data strucure like this:

>structList = 
>{'Sun':{'Sun.1':['Sun1.1','Sun1.2'],'Sun.2':['Sun2.1','Sun2.2']},'Kupa':['Kupa1']}

>I want to transform this into HTML:

><ol>
><li><a href="?a=Sun">Sun</a></li>
>   <ol>
>   <li><a href="?a=Sun.1">Sun.1</a></li>
>     <ol>
>     <li><a href="?a=Sun1.1">Sun1.1</a></li>
>     <li><a href="?a=Sun1.2">Sun1.2</a></li>
>     </ol>
>   <li><a href="?Sun.2">Sun.2</a></li>
>     <ol>
>     <li><a href="?a=Sun2.1">Sun2.1</a></li>
>     <li><a href="?a=Sun2.2">Sun2.2</a></li>
>     </ol>
>   </ol>
><li><a href="?a=Kupa">Kupa</a></li>
>   <ol>
>   <li><a href="?a=Kupa1">Kupa1</a></li>
>   </ol>
></ol>

>If the user clicks on a branch-link say 'Sun.1' then the branch below 
>opens/closes (not printed by the servlet). Like a tree view control in 
>an native GUI app.

>Has this, or a similar approach, been done before in python ( I am using 
>webware/cheetah)?

Here is a browser side solution that you can have a play with:

---------------------------- htmltree.py ---------------------------
import sys

id = 0
def new_id ():
    global id
    id += 1
    return id

def mk_expander (id, lab='+'):
    return '<A href="javascript:void 0;" class="expander" onclick="togglen(%d);" onmouseover="return true;" id="e.%s">%s</A>' % (id,id,lab)

def start_invisible (id):
    return '<DIV id="%d" style="display: none">' % id

def finish_invisible (dst):
    dst.write ('</DIV>')

def build_tree (dst, node):
    dst.write ('<ol>\n')
    for branch in node:
        ##sys.stderr.write ('-- %s\n'%branch)
        id = new_id()
        if type(node) == type([]):
            dst.write ('<li>%s\n' % branch)
        else:
            dst.write ('<li>%s\n%s' % (mk_expander (id,branch),
                                       start_invisible(id)))
            build_tree (dst, node[branch])
            finish_invisible (dst)

style_stuff = '''
<style type="text/css">
A.expander {border-style: solid; border-width: thin 0 thin thin}
A {text-decoration: none}
.mono {font-family : monospace}
TD {text-align : right}
TR.col {background: #9F9 }
.link {background: #99f;
       border-style : solid}
</style>'''

print '<HEAD><TITLE>BLAH</TITLE>'
print '<script src="hier.js"></script>'
print style_stuff
print '''
</HEAD>
<body>
'''

structList = {'Sun':{'Sun.1':['Sun1.1','Sun1.2'],'Sun.2':['Sun2.1','Sun2.2']},'Kupa':['Kupa1']}

build_tree (sys.stdout, structList)
print '</body>\n</html>\n'

-----------------------------------------------------------------

and the javascript file that goes with it


---------------------------------hier.js --------------------------
visibility_state = new Array();
highlighted  = new Array();
selected_node = null;
selected_id = null;
function get_visibility (id) {
    var m = visibility_state[id];
    if (m == undefined)
        m = "none";
    return m;
}
function set_visibility (id, e, vis) {
    e.style.display = vis;
    visibility_state[id] = vis;
}
function togglen(id) {
    toggle_branch (id);
    do_select (id);
    return false;
}
function toggle_branch(id) {
    var e = document.getElementById(id);
    var m = get_visibility (id);
    if (m == "none")
        m = "inline";
    else
        m = "none";
    set_visibility (id, e, m);
}
function show_branch (id) {
    var e = document.getElementById(id);
    set_visibility (id, e, "inline");
}
function hide_branch (id) {
    var e = document.getElementById(id);
    set_visibility (id, e, "none");
}
function do_select (id) {
    if (selected_id != null) {
        var e = document.getElementById("e."+selected_id);
        e.style.backgroundColor = 'transparent';
    }
    var n = document.getElementById("e."+id);
    n.style.backgroundColor = 'red';
    selected_node = document.getElementById(id);
    selected_id = id;
}
function set_visibility_all (n, vis) {
    if (n == null) return false;
    if (n.nodeType == 1) {
        if (n.tagName == "DIV" && n.id != "")
            set_visibility (n.id, n, vis);
        for (var c = n.firstChild; c != null; c = c.nextSibling)
            set_visibility_all (c, vis);
    }
}

-------------------------------------------------------------------

the javascript code is extracted from a larger set of functions that include a
popup menu with inbuilt search (which opens tree levels as necessary), if
you're interested.

Eddie





More information about the Python-list mailing list