- MOZILLA, FIREFOX, SEAMONKEY























|
|
XUL tree NEW - Adding nodes with a context menu / edit node names example/tutorial
The XUL language is very powerful. Powerful enough to forget traditional means of doing
web applications with HTML and using the many widget available with XUL.
This example - a different implementation of the other XUL TREE example -
shows how to add nodes by right-clicking on a node or item and selecting the context-menu
"Add Node" or "Add Root Node". A prompt shows up where you can enter the name, and after clicking on OK, the
node is added. Furthermore the name of the node can be edited - different to the other TREE example -
it can be edited with a simple javascript-prompt. This is more reliable than the other geeky method :-)
In combination with AJAX this is a very powerful tool:
AJAX/Javascript Form GET Request
AJAX/Javascript Form POST Request
AJAX/Javascript XML Processing Example/Tutorial
In the main file, which is opened with the browser, we have a lot of XUL tags.
The primary structure is the XUL TREE and the context-menu (popupset).
newtree.xul
<?xml version="1.0"?>
<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
<?xml-stylesheet href="newtree.css" type="text/css"?>
<window id="example-window" title="Example 6.2.1"
xmlns:html="http://www.w3.org/1999/xhtml"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<script type="application/x-javascript">
<![CDATA[
function getthetree() {
return document.getElementById('thetree');
}
]]>
</script>
<popupset>
<popup id="clipmenu" onpopupshowing="checking(event.target.id);">
<menuitem label="Add Root-Node" oncommand="getthetree().
topcategory('thetreechildren', prompt('Please enter a categoryname','Name of Category'));"/>
<menuitem label="Add Node" oncommand="getthetree().CreateSubTree('thetree', '');"/>
<menuitem label="Delete" oncommand="getthetree().DeleteCurrent('thetree');"/>
<menuitem label="Rename" oncommand="getthetree().RenameCurrent('thetree','category');"/>
</popup>
</popupset>
<tree id="thetree" flex="1" context="clipmenu">
<treecols>
<treecol id="category" label="Name" primary="true" flex="1"/>
</treecols>
<treechildren id="thetreechildren">
<treeitem container="true" open="true" id="treeitem1">
<treerow id="treerow1">
<treecell id="cell-of-treeitem1" label="cell1" onselect="alert('fssfsf');" />
</treerow>
<treechildren>
<treeitem id="treeitem2">
<treerow id="treerow2">
<treecell id="cell-of-treeitem2" label="cell2" value="1"/>
</treerow>
</treeitem>
<treeitem id="treeitem3">
<treerow id="treerow3">
<treecell id="cell-of-treeitem3" label="cell3"/>
</treerow>
</treeitem>
</treechildren>
</treeitem>
<treeitem id="treeitem4">
<treerow id="treerow4" >
<treecell id="cell-of-treeitem4" label="cell4"/>
</treerow>
</treeitem>
</treechildren>
</tree>
</window>
...we bind the XML file (that includes all javascript functions) to the XUL file with
the CSS style sheet:
newtree.css
tree {
-moz-binding: url("newtree.xml#mytree");
-moz-user-focus: normal !important;
-moz-user-select: text;
}
...and here is the XUL file, which will provide the javascript code for the XUL file:
newtree.xml
Based on the now closed(?) OS project MozillaVault
<?xml version="1.0"?>
<bindings id="treeBindings"
xmlns="http://www.mozilla.org/xbl"
xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<binding id="mytree" extends="chrome://global/content/bindings/tree.xml#tree">
<content>
<children includes="treecols"/>
<xul:stack flex="1">
<xul:treerows class="tree-rows" flex="1">
<children/>
</xul:treerows>
</xul:stack>
</content>
<implementation>
<field name="itemid">5</field>
<field name="rowid">5</field>
<field name="treechildrenid">0</field>
<field name="cnt">0</field>
<method name="RenameCurrent">
<parameter name="treename"/>
<parameter name="cellname"/>
<body>
<![CDATA[
var tree = document.getElementById(treename);
var currentitem = tree.treeBoxObject.view.getItemAtIndex(tree.currentIndex);
var currentlabel = tree.treeBoxObject.view.getCellText(tree.currentIndex,cellname);
var newlabel = prompt("Please enter the new node-name",currentlabel);
if (newlabel!=false) {
var currentcell = document.getElementById("cell-of-" +
currentitem.getAttribute("id"));
currentcell.setAttribute("label",newlabel);
}
this.BuildPopups();
]]>
</body>
</method>
<method name="DeleteCurrent">
<parameter name="treename"/>
<body>
<![CDATA[
if (confirm("Are you sure you want to delete this node?") == true) {
var tree = document.getElementById(treename);
var currentelement = tree.treeBoxObject.view.getItemAtIndex(tree.currentIndex);
currentelement.parentNode.removeChild(currentelement);
}
]]>
</body>
</method>
<method name="CreateSubTree">
<parameter name="treeid"/>
<parameter name="content"/>
<body>
<![CDATA[
var tree = document.getElementById(treeid);
var currentitem = tree.treeBoxObject.view.getItemAtIndex(tree.currentIndex);
var currentid = tree.treeBoxObject.view.getItemAtIndex(
tree.currentIndex).getAttribute("id");
if (currentid != "") {
content = prompt('Please enter a node-name','undefined');
var parentid = tree.treeBoxObject.view.getItemAtIndex(
tree.currentIndex).parentNode.getAttribute("id");
var parent = tree.treeBoxObject.view.getItemAtIndex(tree.currentIndex).parentNode;
// create Treerow with id (rowid is a global variable so that
// we do not use the same id twice)
var tr = document.createElement("treerow");
tr.setAttribute("id", "treerow" + this.rowid);
var tc = document.createElement("treecell");
tc.setAttribute("label", content);
tc.setAttribute("id","cell-of-treeitem" + this.itemid);
tr.appendChild(tc);
this.rowid++;
// create treeitem with id (itemid is a global variable so
// that we do not use the same id twice)
var ti = document.createElement("treeitem");
ti.setAttribute("id", "treeitem" + this.itemid);
ti.appendChild(tr);
this.itemid++;
// we distinguish the case that
// the container of the item is empty --> create new treechildren
// object and append item a treechildren-object already exists -->
// get the id and append new item to this one
if (currentitem.getAttribute("container") != "true") {
currentitem.setAttribute("container", "true");
var tch = document.createElement("treechildren");
tch.setAttribute("id", "treechildren" + this.treechildrenid);
tch.appendChild(ti);
this.treechildrenid++;
currentitem.appendChild(tch);
} else {
var existingtreechildren =
document.getElementById(currentitem.childNodes.item(0).getAttribute("id"));
existingtreechildren.appendChild(ti);
}
// set open status of the item
currentitem.setAttribute("open", "true");
}
]]>
</body>
</method>
<method name="topcategory">
<parameter name="childrenobject"/>
<parameter name="content"/>
<body>
<![CDATA[
thetree = document.getElementById(childrenobject);
var tr = document.createElement("treerow");
tr.setAttribute("id", "treerow" + this.rowid);
this.rowid++;
var tc = document.createElement("treecell");
tc.setAttribute("label", content);
tc.setAttribute("id","cell-of-treeitem" + this.itemid);
tr.appendChild(tc);
this.rowid++;
var ti = document.createElement("treeitem");
ti.setAttribute("id", "treeitem" + this.itemid);
ti.appendChild(tr);
this.itemid++;
thetree.appendChild(ti);
]]>
</body>
</method>
<method name="getCellNodeAt">
<parameter name="row"/>
<parameter name="col"/>
<body>
var view;
try {
view = this.contentView;
} catch (ex){}
if (view){
var elem = view.getItemAtIndex(row);
if (elem){
var pos = ((document.getElementById(col).ordinal - 1) >> 1);
return elem.firstChild.childNodes[pos];
}
}
return null;
</body>
</method>
</implementation>
<handlers>
<handler event="click" button="0">
var treeBox = this.treeBoxObject;
var row = {};
var col = {};
var obj = {};
treeBox.getCellAt(event.clientX,event.clientY,row,col,obj);
var cellnode = this.getCellNodeAt(row.value,col.value);
alert(cellnode.id);
</handler>
</handlers>
</binding>
</bindings>
Something noteworthy about the XML file:
We have a "implementation" section and a "handler" section. The "implementation" contains
the javascript functions for our XUL application - the "handler" section contains the event handlers
for the app. Events such as "click" ("onclick" - button 0 = left mouse button, 1 = middle, 2 = right), "dblclick" etc.
Last-Modified: Sat, 04 Feb 2006 16:02:58 GMT
|
|