|
The Tree Widget |
|||||||||||||||||||||||||||
|
[Table of Contents] [Previous: Titled Buttons] [Next: Tab Widget] Feature Owner: David
Hyatt Change History:
The tree widget provides the ability to display multiple items in a tabular format. Each item is represented as a row in the table. Each row may consist of multiple cells. A tree widget has all the same components as an HTML table, and any users of this widget should be thoroughly familiar with the capabilites of HTML tables. Trees can also respond to all of the same CSS properties as HTML tables, as documented in the CSS2 spec on tables. The following tags are roughly analogous to their HTML table counterparts.
To insert a tree widget into a document, use the tree tag. This tag is analogous to the table tag in HTML. The tree widget can contain a caption, which can be specified using the treecaption tag. The tree's column information can be specified using the treecolgroup and treecol tags; these tags respond to all the same properties that the HTML col tags do. These column tags can be used to specify column widths and to apply styles to individual columns in the tree view. Tree column tags can respond to an additional CSS property, column-layout, which indicates whether or not this column's size is alterable using the tree's column resizing capabilities. It has values of fixed and flexible, with the default being flexible. [This is not yet implemented.] A tree can contain headers, bodies, and footers, just as a table does. [Not yet implemented, but coming online soon, so pay attention.] A tree widget's body, unlike a table's body will constrain itself when the height of the table is constrained. The treeitem tag is used to declare a single item (along with that item's row and children) in the tree. The tree item contains one or more rows, which are specified using the treerow tag. Each row consists of one or more cells, which are specified using the treecell tag.
Tree items are either open or closed, and their state is specified using the open attribute. This attribute, when set to true, indicates that the tree item's children should be displayed in the tree. If it is set to false, or if it isn't set at all, then the tree item's children are not displayed. A tree item's children are specified using the treechildren tag, which is placed within the parent treeitem tag. The treechildren tag contains tree items that represent the children of the parent node.
The tree automatically handles selection, and it is capable of supporting single and multiple selection (through the use of CTRL/command and SHIFT modifier keys). The tree's selection is reflected into the content model. Tree items that are selected have an attribute called selected set to true. Tree rows that are selected have an attribute called selectedrow set. Tree cells that are selected have an attribute called selectedcell that is set to true. CSS can be applied using attribute selector rules, thus enabling the tree designer to control the look of the tree's selection. A select handler can be attached to the tree, and this handler will be invoked whenever the tree's selection changes. You can either add it as an attribute (e.g., onselect) on the tree tag or add it using the DOM addEventListener method. The tree widget also supports hover feedback on items and cells. This hover feedback is also reflected into the content model. Tree items that are currently moused over have an attribute called hover set to true. Tree cells that are being moused over have an attribute called hover set to true. Tree rows also use hover. CSS can be applied using attribute selector rules, which enable control of the hover feedback effects for the tree. [This will probably change to use the :hover mechanism at some point, assuming some sort of bubbling mechanism for hover is determined.] Because the tree handles selection, events that would normally go to the content inside the cell are intercepted by the cell. This behavior can be turned off on a cell by cell basis by setting the treeallowevents attribute on the cell. This attribute, when set to true, indicates that the cell is unselectable, and that the content inside should receive events (like mouse clicks and keystrokes). To selectively allow events to go to cell content (e.g., a button inside a cell), the treeallowevents attribute can be placed on a node that is a descendant of the cell. The tree widget supports a selection API that can be used to modify its current selection. This API is outlined below.
Content in a tree cell can be automatically indented based on the node's level in the tree by using the treeindentation tag. The indentation tag can have a width property applied to it using CSS, and this property is multiplied by the node's level of indentation to determine how much padding to insert. The default if no property is specified is 16 pixels per level. [Style support for treeindentation is not yet implemented.] Answers to Common Questions How do I give column headers a visually distinct
look? treehead > treerow > treecell { ... } Can I set the widths of my columns using
percentages? Yes. Click here for details. I don't want the text in my tree cells to wrap. What
do I do? Set the whitespace property on your tree cells in CSS to a value of nowrap. Then constrain the width of your tree (e.g., give your tree a width of 100%). Once you have done this, the contents of the cells will be clipped. I would like the text in my tree cells to be cropped
in addition to being clipped. What do I do? [Not yet implemented.] You will be able to specify this through CSS. If the nowrap property is set and an additional cropstyle property is set (whose value can be left, middle, or right), then the text in the cell can be made to crop. A temporary workaround to get this feature working would be to use titled buttons to hold the text. (See Titled Buttons for details.) Titled buttons already know how to crop right by default when their widths are constrained. I want to use the same event handler for all items in my tree, but I don't want to define these handlers over and over on each node. What do I do? Take advantage of the DOM's event handling capabilities. You can allow events to bubble up to your tree node, and handle the events there. The target of an event that bubbles up can be retrieved using evt.target. When using bubbling on a tree view, it is important to remember that the events will bubble from child node to parent node. Don't think of it like a table, where the events will always go from cell to row to body. If a node is 11 levels deep, then the event will bubble out through the node's parents before getting to the tree body. Be aware of this distinction when writing event-handling code. How do I make the tree's body scroll independently of
the header/footer? How do I make clickable graphical cell contents like
in Messenger (flags, checks, etc.)? Use Titled Buttons. In the click handler for the button, set an attribute on the button to cycle through the various states. Use attribute selector rules for each possible attribute value to set up different images for each state of the button. If desired, the button's border can even be hidden using CSS. How do I hide columns? You can read about this capability here. I want to do insert my
feature here with the tree, but I don't know
where to start! Tree Drag & DropThe main thing to remember during a tree drag is that the event target will be a tree cell, but all of the information about the drag is done at the tree item level. This requires going up two levels in the content tree from the target. Tracking During The DragThe tree item makes use of a DOM event capturer to annotate the item's content node with information about where the drag will go in order to draw the correct drop feedback. The tree needs a little help from the ondragover event handler to trigger the drop feedback magic. The capturer always annotates the tree item with various attributes, but it might not be valid to drop on the tree based on the contents of the drag. When the event handler determines that a drag is valid, it needs to touch the dd-triggerrepaint attribute on the tree item which triggers a repaint with the correct drop feedback. By not touching this attribute, the item will not redraw and this prevents the feedback from appearing. If you don't want drop feedback at all, this is how you'd accomplish it.
Determining Where To DropInstead of placing an ondragdrop event handler on every single tree item, it's easiest to place one on the topmost tree tag and use the target of the event to find the actual drop location. Remember that the tree cell is the actual target and you need to go up two levels to get the to correct tree item. The event capturer sets two attributes on the target tree item during the drag tracking which are useful when the user finally releases the mouse over the tree. The first is dd-droplocation which a boolean which when true indicates that the drop should go before this tree item. If it is false, the drop should go after. The second attribute, dd-dropon, tells if the drop should go on (or into) a container on the tree. When this is true, dd-droplocation is undefined. The tree item determines if something is a container by checking the container attribute of the content node. Here's a simple example which demonstrates how to get the before/after/on information for a handler registered on the tree as a whole.
Customizing Drop Feedback[Not yet implemented] The drop feedback marker bar is normally black, but can be customized on a particular toolbar via CSS. To do this, use the :-moz-drop-marker pseudoelement For example:
[Table of Contents] [Previous: Titled Buttons] [Next: Tab Widget] Contact us at xptoolkitstaff@netscape.com. Want to complain about the new documentation? Email Dave Hyatt. |