-
Notifications
You must be signed in to change notification settings - Fork 1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Patch for lazy node creation #1
Comments
I need this same functionality. captncarrot, could you fork this repo and submit a pull request with your patch? |
sorry, but no. Too much hassle as I have never worked with git. But I will happily give you the whole file, so you can do it :-) And I will also throw in a snippet of how to get rid of a branch - not very elegant as I do little javascript but maybe it helps a bit. I just need to figure out how I attatched the patch previously ... |
My current treeTable.js /*
* jQuery treeTable Plugin 2.3.0
* http://ludo.cubicphuse.nl/jquery-plugins/treeTable/
*
* Copyright 2010, Ludo van den Boom
* Dual licensed under the MIT or GPL Version 2 licenses.
*
* Extended for lazyfill treetable@ewald-arnold.de 2011-08-21
*/
(function($) {
// Helps to make options available to all functions
// TO-DO: This gives problems when there are both expandable and non-expandable
// trees on a page. The options shouldn't be global to all these instances!
var options = {};
var defaultPaddingLeft = {};
$.fn.treeTable = function(opts) {
options = $.extend({}, $.fn.treeTable.defaults, opts);
return this.each(function() {
$(this).addClass("treeTable").find("tbody tr").each(function() {
// Initialize root nodes only if possible
if(!options.expandable || $(this)[0].className.search(options.childPrefix) == -1) {
// To optimize performance of indentation, I retrieve the padding-left
// value of the first root node. This way I only have to call +css+
// once.
if (isNaN(defaultPaddingLeft)) {
defaultPaddingLeft = parseInt($($(this).children("td")[options.treeColumn]).css('padding-left'), 10);
}
initialize($(this));
} else if(options.initialState == "collapsed") {
this.style.display = "none"; // Performance! $(this).hide() is slow...
}
});
});
};
fillRow = function(tr, klass, name, content)
{
var span = document.createElement('span');
span.className = klass;
span.innerHTML = name;
var td = document.createElement('td');
td.appendChild(span);
tr.appendChild(td);
td = document.createElement('td');
td.innerHTML = content;
tr.appendChild(td);
return tr;
};
$.fn.treeTable.createLazyParent = function(id, klass, name, content, parentid)
{
var tr = document.createElement('tr');
tr.id = id;
if (parentid)
tr.className = "lazyfill parent node " + options.childPrefix + parentid;
else
tr.className = "lazyfill parent node";
return fillRow(tr, klass, name, content);
};
$.fn.treeTable.createChild = function(id, klass, name, content, parentid, oddrow)
{
var tr = document.createElement('tr');
tr.id = id;
if(parentid)
parentid = options.childPrefix + parentid;
else
parentid = "";
if(oddrow)
tr.className = "odd " + parentid;
else
tr.className = "even " + parentid;
return fillRow(tr, klass, name, content);
};
$.fn.treeTable.defaults = {
childPrefix: "child-of-",
clickableNodeNames: false,
expandable: true,
indent: 19,
initialState: "collapsed",
treeColumn: 0,
lazyfiller:null
};
// Recursively hide all node's children in a tree
$.fn.collapse = function() {
$(this).addClass("collapsed");
childrenOf($(this)).each(function() {
if(!$(this).hasClass("collapsed")) {
$(this).collapse();
}
this.style.display = "none"; // Performance! $(this).hide() is slow...
});
return this;
};
// Recursively show all node's children in a tree
$.fn.expand = function() {
$(this).removeClass("collapsed").addClass("expanded");
if (options.lazyfiller && $(this).hasClass("lazyfill"))
{
$(this).removeClass("lazyfill");
$(this).addClass("loading");
options.lazyfiller(this);
$(this).removeClass("loading");
}
childrenOf($(this)).each(function() {
initialize($(this));
if($(this).is(".expanded.parent")) {
$(this).expand();
}
// this.style.display = "table-row"; // Unfortunately this is not possible with IE :-(
$(this).show();
});
return this;
};
// Reveal a node by expanding all ancestors
$.fn.reveal = function() {
$(ancestorsOf($(this)).reverse()).each(function() {
initialize($(this));
$(this).expand().show();
});
return this;
};
// Add an entire branch to +destination+
$.fn.appendBranchTo = function(destination) {
var node = $(this);
var parent = parentOf(node);
var ancestorNames = $.map(ancestorsOf($(destination)), function(a) { return a.id; });
// Conditions:
// 1: +node+ should not be inserted in a location in a branch if this would
// result in +node+ being an ancestor of itself.
// 2: +node+ should not have a parent OR the destination should not be the
// same as +node+'s current parent (this last condition prevents +node+
// from being moved to the same location where it already is).
// 3: +node+ should not be inserted as a child of +node+ itself.
if($.inArray(node[0].id, ancestorNames) == -1 && (!parent || (destination.id != parent[0].id)) && destination.id != node[0].id) {
indent(node, ancestorsOf(node).length * options.indent * -1); // Remove indentation
if(parent) { node.removeClass(options.childPrefix + parent[0].id); }
node.addClass(options.childPrefix + destination.id);
move(node, destination); // Recursively move nodes to new location
indent(node, ancestorsOf(node).length * options.indent);
}
return this;
};
// Add an single top level element below tbody
$.fn.appendTopLevelTo = function(destination) {
var node = $(this);
indent(node, ancestorsOf(node).length * options.indent * -1); // Remove indentation
$(destination).children("tbody").append(node[0]);
if (isNaN(defaultPaddingLeft))
defaultPaddingLeft = options.indent;
initialize(node);
return this;
};
// Add reverse() function from JS Arrays
$.fn.reverse = function() {
return this.pushStack(this.get().reverse(), arguments);
};
// Toggle an entire branch
$.fn.toggleBranch = function() {
if($(this).hasClass("collapsed")) {
$(this).expand();
} else {
$(this).removeClass("expanded").collapse();
}
return this;
};
// === Private functions
function ancestorsOf(node) {
var ancestors = [];
while(node = parentOf(node)) {
ancestors[ancestors.length] = node[0];
}
return ancestors;
}
function childrenOf(node) {
return $("table.treeTable tbody tr." + options.childPrefix + node[0].id);
}
function getPaddingLeft(node) {
var paddingLeft = parseInt(node[0].style.paddingLeft, 10);
return (isNaN(paddingLeft)) ? defaultPaddingLeft : paddingLeft;
}
function indent(node, value) {
var cell = $(node.children("td")[options.treeColumn]);
cell[0].style.paddingLeft = getPaddingLeft(cell) + value + "px";
childrenOf(node).each(function() {
indent($(this), value);
});
}
function initialize(node) {
if(!node.hasClass("initialized")) {
node.addClass("initialized");
var childNodes = childrenOf(node);
if(!node.hasClass("parent") && childNodes.length > 0) {
node.addClass("parent");
}
if(node.hasClass("parent")) {
var cell = $(node.children("td")[options.treeColumn]);
var padding = getPaddingLeft(cell) + options.indent;
childNodes.each(function() {
$(this).children("td")[options.treeColumn].style.paddingLeft = padding + "px";
});
if(options.expandable) {
cell.prepend('<span style="margin-left: -' + options.indent + 'px; padding-left: ' + options.indent + 'px" class="expander"></span>');
$(cell[0].firstChild).click(function() { node.toggleBranch(); });
if(options.clickableNodeNames) {
cell[0].style.cursor = "pointer";
$(cell).click(function(e) {
// Don't double-toggle if the click is on the existing expander icon
if (e.target.className != 'expander') {
node.toggleBranch();
}
});
}
// Check for a class set explicitly by the user, otherwise set the default class
if(!(node.hasClass("expanded") || node.hasClass("collapsed"))) {
node.addClass(options.initialState);
}
if(node.hasClass("expanded")) {
node.expand();
}
}
}
}
}
function move(node, destination) {
node.insertAfter(destination);
childrenOf(node).reverse().each(function() { move($(this), node[0]); });
}
function parentOf(node) {
var classNames = node[0].className.split(' ');
for(key in classNames) {
if(classNames[key].match(options.childPrefix)) {
return $("#" + classNames[key].substring(options.childPrefix.length));
}
}
}
})(jQuery); |
current_rows contains a list with all currently existing children of a given branch. var allrows = $("#" + area + "-body").find("tr");
var re = new RegExp("^" + parentname + "-[^-]*$"); // all direct children of current node start with the same name prefix
var rows = [];
allrows.each(function() {
var id = this.id;
var b1 = re.test(id);
var b2 = jQuery.inArray(id, current_rows) >= 0;
if (b1 && !b2)
rows.push("#" + id);
});
if (rows.length != 0)
$(rows).each(function() {
$(this).remove();
}); |
I need to create additional elements on the fly. So I patched treeTable a bit. Not very elegant since I am quite new to jquery ;-)
Usage is like this when adapting index.html from the sources:
The text was updated successfully, but these errors were encountered: