XForms/Tree Menus
Motivation
You want to have a menu that allows you to navigate a tree hierarchy of editable items.
Source Code
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:ev="http://www.w3.org/2001/xml-events" xmlns:xf="http://www.w3.org/2002/xforms"> <head> <title>Hierarchial Tree Menu</title> <link href="tree.css" type="text/css" rel="stylesheet"/> <xf:model id="modelOI"> <xf:instance xmlns="" id="instanceData"> <Data> <currentLot/> <currentItem/> <Lot code=""> <Item code=""/> <Item code=""/> </Lot> <Lot code=""> <Item code=""/> <Item code=""/> <Item code=""/> </Lot> <Lot code=""> <Item code=""/> <Item code=""/> </Lot> </Data> </xf:instance> <xf:bind nodeset="Lot/@code" calculate="position()"/> <xf:bind nodeset="Lot/Item/@code" calculate="position()"/> <xf:instance xmlns="" id="instanceTemplate"> <Data> <Lot code=""> <Item code=""/> </Lot> </Data> </xf:instance> </xf:model> </head> <body> <div id="divMenu"> <xf:output ref="/Data/currentLot"> <xf:label>current Lot : </xf:label> </xf:output> <xf:output ref="/Data/currentItem"> <xf:label>current Item : </xf:label> </xf:output> <ul> <xf:repeat nodeset="/Data/Lot" id="repeatLot"> <li> <a href="#" id="aLot"> <xf:output ref="@code"> <xf:label>lot </xf:label> </xf:output> </a> <xf:action ev:event="DOMActivate" ev:observer="aLot"> <xf:setvalue ref="/Data/currentLot" value="/Data/Lot[index('repeatLot')]/@code"/> <xf:setvalue ref="/Data/currentItem" value="'?'"/> <xf:toggle case="editCode"/> </xf:action> <ul> <xf:repeat nodeset="Item" id="repeatItem"> <li> <a href="#" id="aItem"> <xf:output ref="@code"> <xf:label>item </xf:label> </xf:output> <xf:output ref="."/> </a> <xf:action ev:event="DOMActivate" ev:observer="aItem"> <xf:setvalue ref="/Data/currentLot" value="/Data/Lot[index('repeatLot')]/@code"/> <xf:setvalue ref="/Data/currentItem" value="/Data/Lot[@code=/Data/currentLot]/ Item[position()=index('repeatItem')]/@code"/> <xf:toggle case="editItem"/> </xf:action> </li> </xf:repeat> </ul> </li> </xf:repeat> </ul> <xf:trigger> <xf:label>Insert Lot at last</xf:label> <xf:action ev:event="DOMActivate"> <xf:rebuild/> <xf:recalculate/> <xf:refresh/> <xf:insert nodeset="Lot" at="last()" position="after" origin="instance('instanceTemplate')/Lot"/> <xf:setvalue ref="/Data/currentLot" value="count(/Data/Lot)"/> <xf:setvalue ref="/Data/currentItem" value="/Data/ Lot[count(/Data/Lot)-1]/Item[last()]/@code + 1"/> <xf:rebuild/> <xf:recalculate/> <xf:refresh/> </xf:action> </xf:trigger> <xf:trigger> <xf:label>Insert Item at selected Lot</xf:label> <xf:action ev:event="DOMActivate"> <xf:rebuild/> <xf:recalculate/> <xf:refresh/> <xf:insert nodeset="/Data/Lot[index('repeatLot')]/Item" at="index('repeatItem')" position="after" origin="instance('instanceTemplate')/Lot/Item"/> <xf:rebuild/> <xf:recalculate/> <xf:refresh/> </xf:action> </xf:trigger> </div> <div class="divEdition"> <xf:switch> <xf:case id="editCode"> <xf:group ref="/Data/Lot[@code=/Data/currentLot]"> <fieldset> <legend> Lot n°<xf:output value="@code"/> </legend> <xf:input ref="@code"> <xf:label>code : </xf:label> </xf:input> </fieldset> </xf:group> </xf:case> <xf:case id="editItem"> <xf:group ref="/Data/Lot[@code=/Data/currentLot]/Item[@code=/Data/currentItem]"> <fieldset> <legend> Item n°<xf:output value="@code"/> </legend> <xf:input ref="@code"> <xf:label>item : </xf:label> </xf:input> </fieldset> </xf:group> </xf:case> </xf:switch> </div> </body> </html>
CSS
#divMenu { float: left; width:220px; margin: 0 20px 0 10px; } #divMenu ul { padding: 0 0 5px 5px; } #divMenu li{ color:#000000; } #divMenu li .xf-repeat-item { } #divMenu .xf-repeat-index { font-weight: bold; } #divEdition { float: left; }
Acknowledgments
This example was contributed to the Mozilla XForms Newsgroup by Andy Bailey on Apr 24 2008.