Tree view

We encourage users to post events happening in the community to the community events group on https://www.drupal.org.
kkaefer's picture
  • Features
    • Display tree like structures in a tree
    • Allow the user to select either one item or as many as he wants
    • Collapse items
      • By default, all items are collapsed
      • You can specify if you want to open the path to a certain item
      • The route to a selected item is expanded by default
    • Reorder items (if applicable)
      • Drag one item or a tree of items to another position in the tree
      • After each drag, the user is asked to confirm the action
  • Forms API Array
    • Default elements (of course)
    • All items are in #elements
      • Tree like structure of items
      • Array key is the key/value
      • If the array value is a string, it will be the title of the menu item
      • If it's an array, you have to specify #title (which becomes the title)
        • You can also specify any given key for type=markup
        • You can add a #description
        • Set #expanded to true in order to make the item expanded by default (path to the item gets expanded)
    • #multiple specifies if the user can select more than one item (set to false to allow only one selection)
  • Decisions
    • What markup to use for the tree
      • Tree as table or as unordered/ordered list
      • Advantages of table: developers can add additional actions more easily
      • Advantages of list: Semantically correct(er)

A mockup of a possible forms API array for a tree:

<?php
$form
['tree'] = array(
'#type'       => 'tree',
   
'#title'      => 'This is the title',
  
'#multiple' => false,
'#savehandler' => 'book/js/tree/save',
 
'#savemode' => DRUPAL_TREE_AUTOSAVE | DRUPAL_TREE_CONFIRM_SAVE | DRUPAL_TREE_SUBMIT_SAVE // one of these settings,
   
'#reorderable' => DRUPAL_TREE_REORDER_FREE | DRUPAL_TREE_REORDER_LEVEL // one of these settings,
 
'#collapsible' => true, // false: all menu items are displayed always
'#columns' => array(
     
1 => array(
        
'#title' => t('Item'),
         
'#value' => '%title',
       ),
    
2 => array(
        
'#title' => t('Operations'),
           
'#value' => '<input type="submit" value="'. t('Edit') . '" />',
       )
  ),
'#elements' => array( // quick syntax: 'id' => 'Title'
    
'value1' => 'first item',
      
'value2' => array(
           
'#title' => 'second item',
         
'value3' => 'sub item one',
        
'value4' => 'sub item two',
        
'value5' => array(
               
'#title' => 'sub item three',
              
'#expanded' => true
          
),
     ),
    
'value6' => array(
           
'#title' => 'Third &amp; actually 4<sup>th</sup> item',
        
'#description' => 'If you select this, hell goes loose',
           
'#selected' => true,
         
'#prefix' => '<span class="highlighted">',
         
'#suffix' => '</span>',
       ),
),
);
?>

I know that there are still several issues to cover.

Please share your opinion or ask if something is unclear.

Comments

Konstantin, kindly update us

benc's picture

Konstantin, kindly update us on your recent solutions to your list indention problems. Also, if you are encountering other problems, it may help to post these here -- the others may have ideas to help you solve them! Thanks!

"Work smarter, not harder."
http://digitalsolutions.ph

Tree markup

kkaefer's picture

I think, I'll give an overview on how the markup of the menu tree will look like:

<li class="leaf|collapsed|expanded">
  <div class="item">
    <label><input type="radio">Label
    <ul class="operations">
      <li><a href="edit/N">edit</a></li>
      <li><a href="delete/N">delete</a></li>
    </ul>
  </div>
  [<ul class="menu">
    ...
  </ul>]
</li>

You should get the general idea. Instead of using a table for such listings, I use a nested unsorted list. This is a lot easier to implement, semantically correct and simpler for the JavaScript. The only problem so far was to align the "operations" column properly as every list item is indented differently depending on its depth in the hierarchy. However, this can be solved with CSS: The li is positioned relatively and the ul is positioned absolutely. If there is a position rule in an ancestor, an absolutely positioned element will be positioned relative to this ancester rather than the whole page. This allows us to right:0px and "glue" the operations column to the right side where it belongs to.