META-INF.resources.org.richfaces.tree.js Maven / Gradle / Ivy
The newest version!
/*
* JBoss, Home of Professional Open Source
* Copyright ${year}, Red Hat, Inc. and individual contributors
* by the @authors tag. See the copyright.txt in the distribution for a
* full listing of individual contributors.
*
* This is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/
(function($, rf) {
var NEW_NODE_TOGGLE_STATE = "__NEW_NODE_TOGGLE_STATE";
var TRIGGER_NODE_AJAX_UPDATE = "__TRIGGER_NODE_AJAX_UPDATE";
var SELECTION_STATE = "__SELECTION_STATE";
var TREE_CLASSES = ["rf-tr-nd-colps", "rf-tr-nd-exp"];
var TREE_HANDLE_CLASSES = ["rf-trn-hnd-colps", "rf-trn-hnd-exp"];
var TREE_ICON_CLASSES = ["rf-trn-ico-colps", "rf-trn-ico-exp"];
rf.ui = rf.ui || {};
rf.ui.TreeNode = rf.BaseComponent.extendClass({
name: "TreeNode",
/**
* Backing object for rich:treeNode
*
* @extends RichFaces.BaseComponent
* @memberOf! RichFaces.ui
* @constructs RichFaces.ui.TreeNode
*
* @param id
* @param commonOptions
*/
init: function (id, commonOptions) {
$superTreeNode.constructor.call(this, id);
this.__rootElt = $(this.attachToDom());
this.__children = new Array();
this.__initializeChildren(commonOptions);
var handlers = (commonOptions.clientEventHandlers || {})[this.getId().substring(commonOptions.treeId.length)] || {};
if (handlers.bth) {
rf.Event.bind(this.__rootElt, "beforetoggle", new Function("event", handlers.bth));
}
if (handlers.th) {
rf.Event.bind(this.__rootElt, "toggle", new Function("event", handlers.th));
}
this.__addLastNodeClass();
},
destroy: function() {
if (this.parent) {
this.parent.removeChild(this);
this.parent = null;
}
this.__clientToggleStateInput = null;
this.__clearChildren();
this.__rootElt = null;
$superTreeNode.destroy.call(this);
},
__initializeChildren: function(commonOptions) {
var _this = this;
this.__rootElt.children(".rf-tr-nd").each(function() {
_this.addChild(new rf.ui.TreeNode(this, commonOptions));
});
},
__addLastNodeClass: function() {
if (this.__rootElt.next("div").length == 0) {
this.__rootElt.addClass("rf-tr-nd-last");
}
},
__getNodeContainer: function() {
return this.__rootElt.find(" > .rf-trn:first");
},
__getHandle: function() {
return this.__getNodeContainer().find(" > .rf-trn-hnd:first");
},
__getContent: function() {
return this.__getNodeContainer().find(" > .rf-trn-cnt:first");
},
__getIcons: function() {
return this.__getContent().find(" > .rf-trn-ico");
},
getParent: function() {
return this.__parent;
},
setParent: function(newParent) {
this.__parent = newParent;
},
addChild: function(child, idx) {
var start;
if (typeof idx != 'undefined') {
start = idx;
} else {
start = this.__children.length;
}
this.__children.splice(start, 0, child);
child.setParent(this);
},
removeChild: function(child) {
if (this.__children.length) {
var idx = this.__children.indexOf(child);
if (idx != -1) {
var removedChildren = this.__children.splice(idx, 1);
if (removedChildren) {
for (var i = 0; i < removedChildren.length; i++) {
removedChildren[i].setParent(undefined);
}
}
}
}
},
__clearChildren: function() {
for (var i = 0; i < this.__children.length; i++) {
this.__children[i].setParent(undefined);
}
this.__children = new Array();
},
isExpanded: function() {
return !this.isLeaf() && this.__rootElt.hasClass("rf-tr-nd-exp");
},
isCollapsed: function() {
return !this.isLeaf() && this.__rootElt.hasClass("rf-tr-nd-colps");
},
isLeaf: function() {
return this.__rootElt.hasClass("rf-tr-nd-lf");
},
__canBeToggled: function() {
return !this.isLeaf() && !this.__rootElt.hasClass("rf-tr-nd-exp-nc") && !this.__loading;
},
toggle: function() {
if (!this.__canBeToggled()) {
return;
}
if (this.isCollapsed()) {
this.expand();
} else {
this.collapse();
}
},
__updateClientToggleStateInput: function(newState) {
if (!this.__clientToggleStateInput) {
this.__clientToggleStateInput = $("").appendTo(this.__rootElt)
.attr({name: this.getId() + NEW_NODE_TOGGLE_STATE});
}
this.__clientToggleStateInput.val(newState.toString());
},
__fireBeforeToggleEvent: function() {
return rf.Event.callHandler(this.__rootElt, "beforetoggle");
},
__fireToggleEvent: function() {
rf.Event.callHandler(this.__rootElt, "toggle");
},
__makeLoading: function() {
this.__loading = true;
this.__getNodeContainer().addClass("rf-trn-ldn");
},
__resetLoading: function() {
this.__loading = false;
this.__getNodeContainer().removeClass("rf-trn-ldn");
},
__changeToggleState: function(newState) {
if (!this.isLeaf()) {
if (newState ^ this.isExpanded()) {
if (this.__fireBeforeToggleEvent() === false) {
return;
}
var tree = this.getTree();
switch (tree.getToggleType()) {
case 'client':
this.__rootElt.addClass(TREE_CLASSES[newState ? 1 : 0]).removeClass(TREE_CLASSES[!newState ? 1 : 0]);
this.__getHandle().addClass(TREE_HANDLE_CLASSES[newState ? 1 : 0]).removeClass(TREE_HANDLE_CLASSES[!newState ? 1 : 0]);
var icons = this.__getIcons();
if (icons.length == 1) {
icons.addClass(TREE_ICON_CLASSES[newState ? 1 : 0]).removeClass(TREE_ICON_CLASSES[!newState ? 1 : 0]);
}
this.__updateClientToggleStateInput(newState);
this.__fireToggleEvent();
break;
case 'ajax':
case 'server':
//TODO - event?
tree.__sendToggleRequest(null, this, newState);
break;
}
}
}
},
collapse: function() {
this.__changeToggleState(false);
},
expand: function() {
this.__changeToggleState(true);
},
__setSelected: function(value) {
var content = this.__getContent();
if (value) {
content.addClass("rf-trn-sel");
} else {
content.removeClass("rf-trn-sel");
}
this.__selected = value;
},
isSelected: function() {
return this.__selected;
},
getTree: function() {
return this.getParent().getTree();
},
getId: function() {
return this.__rootElt.attr('id');
}
});
// define super class link for TreeNode
var $superTreeNode = rf.ui.TreeNode.$super;
rf.ui.TreeNode.initNodeByAjax = function(nodeId, commonOptions) {
var node = $(document.getElementById(nodeId));
var opts = commonOptions || {};
var parent = node.parent(".rf-tr-nd, .rf-tr");
var idx = node.prevAll(".rf-tr-nd").length;
var parentNode = rf.component(parent[0]);
opts.treeId = parentNode.getTree().getId();
var newChild = new rf.ui.TreeNode(node[0], opts);
parentNode.addChild(newChild, idx);
var tree = parentNode.getTree();
if (tree.getSelection().contains(newChild.getId())) {
newChild.__setSelected(true);
}
};
rf.ui.TreeNode.emitToggleEvent = function(nodeId) {
var node = document.getElementById(nodeId);
if (!node) {
return;
}
rf.component(node).__fireToggleEvent();
};
var findTree = function(elt) {
return rf.component($(elt).closest(".rf-tr"));
};
var findTreeNode = function(elt) {
return rf.component($(elt).closest(".rf-tr-nd"));
};
var isEventForAnotherTree = function(tree, elt) {
return tree != findTree(elt);
};
rf.ui.Tree = rf.ui.TreeNode.extendClass({
name: "Tree",
/**
* Backing object for rich:tree
*
* @extends RichFaces.ui.TreeNode
* @memberOf! RichFaces.ui
* @constructs RichFaces.ui.Tree
*
* @param id
* @param options
*/
init: function (id, options) {
this.__treeRootElt = $(rf.getDomElement(id));
var commonOptions = {};
commonOptions.clientEventHandlers = options.clientEventHandlers || {};
commonOptions.treeId = id;
$superTree.constructor.call(this, this.__treeRootElt, commonOptions);
this.__toggleType = options.toggleType || 'ajax';
this.__selectionType = options.selectionType || 'client';
if (options.ajaxSubmitFunction) {
this.__ajaxSubmitFunction = new Function("event", "source", "params", "complete", options.ajaxSubmitFunction);
}
if (options.onbeforeselectionchange) {
rf.Event.bind(this.__treeRootElt, "beforeselectionchange", new Function("event", options.onbeforeselectionchange));
}
if (options.onselectionchange) {
rf.Event.bind(this.__treeRootElt, "selectionchange", new Function("event", options.onselectionchange));
}
this.__toggleNodeEvent = options.toggleNodeEvent;
if (this.__toggleNodeEvent) {
this.__treeRootElt.on( this.__toggleNodeEvent, ".rf-trn", this, this.__nodeToggleActivated);
}
if (!this.__toggleNodeEvent || this.__toggleNodeEvent != 'click') {
this.__treeRootElt.on( "click", ".rf-trn-hnd", this, this.__nodeToggleActivated);
}
this.__treeRootElt.on( "mousedown", ".rf-trn-cnt", this, this.__nodeSelectionActivated);
this.__findSelectionInput();
this.__selection = new rf.ui.TreeNodeSet(this.__selectionInput.val());
$(document).ready($.proxy(this.__updateSelectionFromInput, this));
},
__findSelectionInput: function () {
this.__selectionInput = $(" > .rf-tr-sel-inp", this.__treeRootElt);
},
__addLastNodeClass: function() {
//stub function overriding parent class method
},
destroy: function() {
if (this.__toggleNodeEvent) {
this.__treeRootElt.off(this.__toggleNodeEvent, ".rf-trn", this.__nodeToggleActivated);
}
if (!this.__toggleNodeEvent || this.__toggleNodeEvent != 'click') {
this.__treeRootElt.off("click",".rf-trn-hnd", this.__nodeToggleActivated);
}
this.__treeRootElt.off("mousedown", ".rf-trn-cnt", this.__nodeSelectionActivated);
this.__treeRootElt = null;
this.__selectionInput = null;
this.__ajaxSubmitFunction = null;
$superTree.destroy.call(this);
},
__nodeToggleActivated: function(event) {
var theTree = event.data;
if (isEventForAnotherTree(theTree, this)) {
return;
}
var treeNode = findTreeNode(this);
treeNode.toggle();
},
__nodeSelectionActivated: function(event) {
var theTree = event.data;
if (isEventForAnotherTree(theTree, this)) {
return;
}
var treeNode = findTreeNode(this);
if (event.ctrlKey) {
theTree.__toggleSelection(treeNode);
} else {
theTree.__addToSelection(treeNode);
}
},
__sendToggleRequest: function(event, toggleSource, newNodeState) {
var toggleSourceId = toggleSource.getId();
var clientParams = {};
clientParams[toggleSourceId + NEW_NODE_TOGGLE_STATE] = newNodeState;
if (this.getToggleType() == 'server') {
var form = this.__treeRootElt.closest('form');
rf.submitForm(form, clientParams);
} else {
toggleSource.__makeLoading();
clientParams[toggleSourceId + TRIGGER_NODE_AJAX_UPDATE] = newNodeState;
this.__ajaxSubmitFunction(event, toggleSourceId, clientParams, function() {
var treeNode = rf.component(toggleSourceId);
if (treeNode) {
treeNode.__resetLoading();
}
});
}
},
getToggleType: function() {
return this.__toggleType;
},
getSelectionType: function() {
return this.__selectionType;
},
getTree: function() {
return this;
},
__handleSelectionChange: function(newSelection) {
var eventData = {
oldSelection: this.getSelection().getNodes(),
newSelection: newSelection.getNodes()
};
if (rf.Event.callHandler(this.__treeRootElt, "beforeselectionchange", eventData) === false) {
return;
}
this.__selectionInput.val(newSelection.getNodeString());
if (this.getSelectionType() == 'client') {
this.__updateSelection(newSelection);
} else {
this.__ajaxSubmitFunction(null, this.getId());
}
},
__toggleSelection: function(node) {
var newSelection = this.getSelection().cloneAndToggle(node);
this.__handleSelectionChange(newSelection);
},
__addToSelection: function(node) {
var newSelection = this.getSelection().cloneAndAdd(node);
this.__handleSelectionChange(newSelection);
},
__updateSelectionFromInput: function() {
this.__findSelectionInput();
this.__updateSelection(new rf.ui.TreeNodeSet(this.__selectionInput.val()));
},
__updateSelection: function(newSelection) {
var oldSelection = this.getSelection();
oldSelection.each(function() {
this.__setSelected(false)
});
newSelection.each(function() {
this.__setSelected(true)
});
if (oldSelection.getNodeString() != newSelection.getNodeString()) {
rf.Event.callHandler(this.__treeRootElt, "selectionchange", {
oldSelection: oldSelection.getNodes(),
newSelection: newSelection.getNodes()
});
}
this.__selection = newSelection;
},
getSelection: function() {
return this.__selection;
},
__getMenuSelector: function (menu) {
var selector = "[id='" + this.id[0].id + "'] ";
selector += (typeof menu.options.targetSelector === 'undefined')
? ".rf-trn-cnt" : menu.options.targetSelector;
selector = $.trim(selector);
return selector;
},
contextMenuAttach: function (menu) {
var selector = this.__getMenuSelector(menu);
rf.Event.bind(selector, menu.options.showEvent, $.proxy(menu.__showHandler, menu), menu);
},
contextMenuDetach: function (menu) {
var selector = this.__getMenuSelector(menu);
rf.Event.unbind(selector, menu.options.showEvent);
}
});
// define super class link for Tree
var $superTree = rf.ui.Tree.$super;
rf.ui.TreeNodeSet = function() {
this.init.apply(this, arguments);
};
//TODO - that's a single-node set, implement multi-node support!
$.extend(rf.ui.TreeNodeSet.prototype, {
init: function(nodeId) {
this.__nodeId = nodeId;
},
contains: function(node) {
if (node.getId) {
return this.__nodeId == node.getId();
} else {
return this.__nodeId == node;
}
},
getNodeString: function() {
return this.__nodeId;
},
toString: function() {
return this.getNodeString();
},
getNodes: function() {
if (this.__nodeId) {
var node = rf.component(this.__nodeId);
if (node) {
return [node];
} else {
return null;
}
}
return [];
},
cloneAndAdd: function(node) {
return new rf.ui.TreeNodeSet(node.getId());
},
cloneAndToggle: function(node) {
var nodeId;
if (this.contains(node)) {
nodeId = "";
} else {
nodeId = node.getId();
}
return new rf.ui.TreeNodeSet(nodeId);
},
each: function(callback) {
$.each(this.getNodes() || [], callback);
}
});
}(RichFaces.jQuery, RichFaces));
© 2015 - 2025 Weber Informatics LLC | Privacy Policy