| | |
| | | |
| | | // insert as child of an existing node |
| | | if (parent_node) { |
| | | node.level = parent_node.level + 1; |
| | | if (!parent_node.children) |
| | | parent_node.children = []; |
| | | |
| | |
| | | } |
| | | // insert at top level |
| | | else { |
| | | node.level = 0; |
| | | data.push(node); |
| | | li = render_node(node, container); |
| | | } |
| | |
| | | */ |
| | | function update_data() |
| | | { |
| | | data = walk_list(container); |
| | | data = walk_list(container, 0); |
| | | } |
| | | |
| | | /** |
| | |
| | | function update_dom(node) |
| | | { |
| | | var li = id2dom(node.id); |
| | | li.attr('aria-expanded', node.collapsed ? 'false' : 'true'); |
| | | li.children('ul').first()[(node.collapsed ? 'hide' : 'show')](); |
| | | li.children('div.treetoggle').removeClass('collapsed expanded').addClass(node.collapsed ? 'collapsed' : 'expanded'); |
| | | me.triggerEvent('toggle', node); |
| | |
| | | |
| | | // render child nodes |
| | | for (var i=0; i < data.length; i++) { |
| | | data[i].level = 0; |
| | | render_node(data[i], container); |
| | | } |
| | | |
| | |
| | | |
| | | // add child list and toggle icon |
| | | if (node.children && node.children.length) { |
| | | li.attr('aria-expanded', node.collapsed ? 'false' : 'true'); |
| | | $('<div class="treetoggle '+(node.collapsed ? 'collapsed' : 'expanded') + '"> </div>').appendTo(li); |
| | | var ul = $('<ul>').appendTo(li).attr('class', node.childlistclass).attr('role', 'tree'); |
| | | var ul = $('<ul>').appendTo(li).attr('class', node.childlistclass).attr('role', 'group'); |
| | | if (node.collapsed) |
| | | ul.hide(); |
| | | |
| | | for (var i=0; i < node.children.length; i++) { |
| | | node.children[i].level = node.level + 1; |
| | | render_node(node.children[i], ul); |
| | | } |
| | | } |
| | |
| | | * Recursively walk the DOM tree and build an internal data structure |
| | | * representing the skeleton of this tree list. |
| | | */ |
| | | function walk_list(ul) |
| | | function walk_list(ul, level) |
| | | { |
| | | var result = []; |
| | | ul.children('li').each(function(i,e){ |
| | |
| | | id: dom2id(li), |
| | | classes: li.attr('class').split(' '), |
| | | virtual: li.hasClass('virtual'), |
| | | level: level, |
| | | html: li.children().first().get(0).outerHTML, |
| | | children: walk_list(sublist) |
| | | children: walk_list(sublist, level+1) |
| | | } |
| | | |
| | | if (sublist.length) { |
| | |
| | | } |
| | | if (node.children.length) { |
| | | node.collapsed = sublist.css('display') == 'none'; |
| | | li.attr('aria-expanded', node.collapsed ? 'false' : 'true'); |
| | | } |
| | | if (li.hasClass('selected')) { |
| | | li.attr('aria-selected', 'true'); |
| | |
| | | } |
| | | |
| | | // declare list item as treeitem |
| | | li.attr('role', 'treeitem'); |
| | | li.attr('role', 'treeitem').attr('aria-level', node.level+1); |
| | | |
| | | // allow virtual nodes to receive focus |
| | | if (node.virtual) { |
| | |
| | | indexbyid[node.id] = node; |
| | | }); |
| | | |
| | | ul.attr('role', 'tree'); |
| | | ul.attr('role', level == 0 ? 'tree' : 'group'); |
| | | |
| | | return result; |
| | | } |
| | |
| | | var mod = dir < 0 ? 'prev' : 'next', |
| | | next = li[mod](), limit, parent; |
| | | |
| | | if (dir > 0 && !from_child && li.children('ul[role=tree]:visible').length) { |
| | | if (dir > 0 && !from_child && li.children('ul[role=group]:visible').length) { |
| | | li.children('ul').children('li:first').children('a:first').focus(); |
| | | } |
| | | else if (dir < 0 && !from_child && next.children('ul[role=tree]:visible').length) { |
| | | else if (dir < 0 && !from_child && next.children('ul[role=group]:visible').length) { |
| | | next.children('ul').children('li:last').children('a:last').focus(); |
| | | } |
| | | else if (next.length && next.children('a:first')) { |