Hi there,
Taking my first steps in Prototype and reading this very helpful book
by Christophe Porteneuve. There's an interesting tutorial (Chpt. 7) on
making a tree to organize staff members. The problem is that I can't
make it working in IE. In Firefox it works just great.
Did anybody fiddle with it? Maybe somebody has already figured it out.
IE says "'undefined' is null or not an object" for n.container =
nodes; from the init method:
......
init: function(id, nodes) {
id = id || 'staff';
nodes = nodes || this.nodes;
nodes.each(function(n) {
n.container = nodes;
this.createDOMFragment(id, n);
if (n.children)
this.init(n.id, n.children);
}.bind(this));
},
......
In IE nothing works at all, though the tree loads properly
Here's the full code of people.js:
---------------------------------------------
var Staff = {
_templates: {
person: new Template(
'<span class="person">' +
'<input type="checkbox" name="item[]" value="#{id}" /
><span>#{name}</span></span>'),
group: new Template(
'<span class="group">' +
'<a href="" title="Click to collapse">' +
'<img class="toggler" src="group_open.gif" alt="-" /></a>' +
'<input type="checkbox" name="item[]" value="#{id}" /
><span>#{name}</span></span>' +
'<ul></ul>')
},
_currentId: 1000,
selected: null,
nodes: [
{ id: 'item1', name: 'ACME',
children: [
{ id: 'item11', name: 'IT',
children: [
{ id: 'item111', name: 'Sébastien Gruhier' },
{ id: 'item112', name: 'Alexis Jaubert' },
{ id: 'item113', name: 'Guillaume Réan' }
] },
{ id: 'item12', name: 'HR',
children: [
{ id: 'item121', name: 'Sandrine Daspet' }
] },
{ id: 'item13', name: 'Xavier Borderie' }
] },
],
create: function(name, isGroup) {
var container = this.selected ? this.selected.children :
this.nodes;
var node = { id: 'item' + this.genId(), name: name, container:
container };
if (isGroup)
node.children = [];
container.push(node);
return this.createDOMFragment(
this.selected ? this.selected.id : 'staff', node);
},
createDOMFragment: function(parentId, node) {
var element = new Element('li', { id: node.id });
var tpl = this._templates[node.children ? 'group' : 'person'];
var escapedNode = { id: node.id, name: node.name.escapeHTML() };
element.update(tpl.evaluate(escapedNode));
$(parentId).down('ul').appendChild(element);
element.down('input').checked = node.checked;
this.makeVisible(node.id);
return node;
},
find: function(id, nodes) {
nodes = nodes || this.nodes;
var result;
nodes.each(function(n) {
result = n.id == id ? n : n.children && this.find(id,
n.children);
if (result)
throw $break;
}.bind(this));
return result;
},
genId: function() {
return ++this._currentId;
},
init: function(id, nodes) {
id = id || 'staff';
nodes = nodes || this.nodes;
nodes.each(function(n) {
n.container = nodes;
this.createDOMFragment(id, n);
if (n.children)
this.init(n.id, n.children);
}.bind(this));
},
makeVisible: function(id) {
var elt = $(id);
// Open all containing groups
while (elt = elt.up('ul'))
if (!elt.visible())
this.toggle(elt.up('li').id);
},
removeSelected: function() {
if (!this.selected)
throw 'No selection to remove';
var container = this.selected.container;
container = container.without(this.selected);
var elt = $(this.selected.id);
var previous = elt.previous('li');
if (!previous)
previous = elt.up('li');
elt.remove();
this.selected = null;
if (previous)
this.select(previous.id);
else
this.updateEditor();
},
select: function(id) {
if (this.selected)
$(this.selected.id).down('span').removeClassName('selected');
this.selected = (this.selected && this.selected.id == id
? null : this.find(id));
if (this.selected) {
var elt = $(id);
elt.down('span').addClassName('selected');
this.makeVisible(id);
}
this.updateEditor();
return this.selected;
},
toggle: function(id) {
var elt = $(id);
var group = elt.down('ul');
var toggler = elt.down('img');
var groupIsVisible = group.toggle().visible();
toggler.src = 'group_' + (groupIsVisible ? 'open' : 'closed') +
'.gif';
toggler.alt = (groupIsVisible ? '-' : '+');
toggler.up('a').title = 'Click to ' +
(groupIsVisible ? 'collapse' : 'expand');
},
update: function() {
this.selected.label = $F('edtName');
$(this.selected.id).down('span', 1).update(
this.selected.label.escapeHTML());
},
updateEditor: function() {
if (!this.selected) {
$('edtName').value = '';
$('chkIsGroup').enable().checked = false;
$('btnSubmit').value = 'Create';
$('btnRemove', 'btnAddChild', 'btnSubmit').invoke('disable');
} else {
$('edtName').value = this.selected.name;
var isGroup = this.selected.children;
$('chkIsGroup').checked = isGroup;
$('btnSubmit').value = 'Rename';
$('btnRemove').enable();
$('btnAddChild', 'chkIsGroup').invoke(isGroup ? 'enable' :
'disable');
}
$('edtName').activate();
}
}; // Staff
function handleTreeClick(e) {
var elt = e.element();
if (elt.tagName == 'INPUT')
return;
e.stop();
if (elt.tagName == 'IMG')
elt = elt.up('a');
if (elt.tagName == 'A') {
Staff.toggle(elt.up('li').id);
return;
}
// Other click. Let's select if we're on a valid item!
if ('LI' != elt.tagName)
elt = elt.up('li');
if (!elt)
return;
Staff.select(elt.id);
} // handleTreeClick
function processForm(e, addChild) {
e.stop();
if (Staff.selected && !addChild)
Staff.update($F('edtName'));
else
Staff.create($F('edtName'), $('chkIsGroup').checked);
} // processForm
document.observe('dom:loaded', function() {
Staff.init();
Staff.updateEditor();
$('tree').observe('click', handleTreeClick);
$('editor').observe('submit', processForm);
$('btnRemove').observe('click', Staff.removeSelected.bind(Staff));
$('btnAddChild').observe('click',
processForm.bindAsEventListener(this, true));
new Field.Observer('edtName', 0.3, function() {
$('btnSubmit').disabled = $F('edtName').blank();
});
});
---------------------------------------------
people.html:
---------------------------------------------
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://
www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Organizing your staff</title>
<link rel="stylesheet" type="text/css" href="people.css">
<script type="text/javascript" src="prototype.js"></script>
<script type="text/javascript" src="people.js"></script>
</head>
<body>
<h1>Organizing your staff</h1>
<div id="tree" >
<h2>Your staff</h2>
<form id="staff" >
<ul>
</ul>
</form>
</div>
<div id="props" >
<h2>Item properties</h2>
<form id="editor" >
<p>
<label for="edtName" accesskey="N" >Name:</label>
<input type="text" id="edtName" />
</p>
<p>
<input type="checkbox" id="chkIsGroup" />
<label for="chkIsGroup" id="lblIsGroup"
accesskey="G" >Is a group?</label>
</p>
<p>
<input type="button" id="btnRemove" value="Remove"
accesskey="R" />
<input type="button" id="btnAddChild" value="Add as child"
accesskey="C" />
<input type="submit" id="btnSubmit" value="Create" />
</p>
</form>
</div>
</body>
</html>
---------------------------------------------
and people.css:
---------------------------------------------
body { font-family: sans-serif; font-size: small; }
h1 { color: navy; font-size: x-large; font-weight: normal; }
h2 {
color: green; font-size: larger;
border-bottom: 1px solid green; margin: 0 0 0.5em;
}
img { border: 0; }
#tree {
width: 25em; height: 30em; overflow: auto; float: left;
border: 1px solid #444; background: #eee; padding: 0.5em;
cursor: default;
}
#props {
width: 25em; height: 10em; margin-left: 27em;
border: 1px solid #444; background: #eee; padding: 0.5em;
}
#tree ul {
list-style-type: none;
margin: 0; padding: 0;
}
#tree ul ul { padding-left: 1.3em; } /* <label
id="code.dom.style.dynamic1"/> */
#tree li { padding-left: 0.1em; margin: 0.4em 0; }
#tree span { padding: 5px; }
span.group { font-weight: bold; }
#tree span.person { font-weight: normal; margin-left: 16px; }
#tree span.selected {
border: 1px solid #004; padding: 4px; background: #ddf;
color: navy;
} /* <label id="code.dom.style.dynamic2"/> */
#editor p { position: relative; height: 1.3em; }
#edtName, #chkIsGroup { position: absolute; left: 4em; margin-left:
0; }
#edtName { padding: 0 0.1em; right: 0; }
#edtName:focus, #edtName:active { border: 2px solid black;
background: #ffd; }
#lblIsGroup { position: absolute; left: 6.3em; }
---------------------------------------------
I'm using Prototype v. 1.6.0
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups "Ruby
on Rails: Spinoffs" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at
http://groups.google.com/group/rubyonrails-spinoffs?hl=en
-~----------~----~----~----~------~----~------~--~---