blob: 04a68997cd335142a1e2647aaa5ac517d1ed2928 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import {Listener, Phase} from "./tobago-listener";
import {Tobago4Utils} from "./tobago-utils";
class Tree {
static toggleNode = function ($element, event) {
var src;
var $node = $element.closest(".tobago-treeNode, .tobago-treeMenuNode");
var $data = $node.closest(".tobago-treeMenu, .tobago-tree, .tobago-sheet");
var $expanded = $data.children(".tobago-treeMenu-expanded, .tobago-tree-expanded, .tobago-sheet-expanded");
var $toggles = $node.find(".tobago-treeMenuNode-toggle, .tobago-treeNode-toggle");
var rowIndex = Tree.rowIndex($node);
if (Tree.isExpanded($node, $expanded)) {
Tree.hideChildren($node);
$toggles.find("i").each(function () {
var $toggle = jQuery(this);
$toggle.removeClass($toggle.data("tobago-open")).addClass($toggle.data("tobago-closed"));
});
$toggles.find("img").each(function () {
var $toggle = jQuery(this);
src = $toggle.data("tobago-closed");
if (src === undefined) { // use the open icon if there is no close icon
src = $toggle.data("tobago-open");
}
$toggle.attr("src", src);
});
$expanded.val($expanded.val().replace(new RegExp("," + rowIndex + ","), ","));
$node.filter(".tobago-treeNode").removeClass("tobago-treeNode-markup-expanded");
$node.filter(".tobago-treeMenuNode").removeClass("tobago-treeMenuNode-markup-expanded");
} else {
var reload = Tree.showChildren($node, $expanded);
$expanded.val($expanded.val() + rowIndex + ",");
if (reload) {
jsf.ajax.request(
$toggles.parent().attr("id"),
event,
{
//"javax.faces.behavior.event": "click",
execute: $data.attr("id"),
render: $data.attr("id")
});
} else {
$toggles.find("i").each(function () {
var $toggle = jQuery(this);
$toggle.removeClass($toggle.data("tobago-closed")).addClass($toggle.data("tobago-open"));
});
$toggles.find("img").each(function () {
var $toggle = jQuery(this);
src = $toggle.data("tobago-open");
if (src === undefined) { // use the close icon if there is no open icon
src = $toggle.data("tobago-closed");
}
$toggle.attr("src", src);
});
$node.filter(".tobago-treeNode").addClass("tobago-treeNode-markup-expanded");
$node.filter(".tobago-treeMenuNode").addClass("tobago-treeMenuNode-markup-expanded");
}
}
};
/**
* Hide all children of the node recursively.
* @param node A jQuery-Object as a node of the tree.
*/
static hideChildren = function (node) {
var inSheet = Tree.isInSheet(node);
var children = Tree.findChildren(node);
children.each(function () {
if (inSheet) {
jQuery(this).parent().parent().hide();
} else {
jQuery(this).hide();
}
Tree.hideChildren(jQuery(this));
});
};
/**
* Show the children of the node recursively, there parents are expanded.
* @param node A jQuery-Object as a node of the tree.
* @return is reload needed (to get all nodes from the server)
*/
static showChildren = function (node, expanded) {
var inSheet = Tree.isInSheet(node);
var children = Tree.findChildren(node);
if (children.length == 0) {
// no children in DOM, reload it from the server
return true;
}
children.each(function () {
var child = jQuery(this);
if (inSheet) {
child.parent().parent().show();
} else {
child.show();
}
if (Tree.isExpanded(child, expanded)) {
var reload = Tree.showChildren(child, expanded);
if (reload) {
return true;
}
}
});
return false;
};
static init = function (elements) {
elements = elements.jQuery ? elements : jQuery(elements); // fixme jQuery -> ES5
Tobago4Utils.selectWithJQuery(elements, ".tobago-treeNode-markup-folder .tobago-treeNode-toggle").click(function (event) {
Tree.toggleNode(jQuery(this), event);
return false;
});
Tobago4Utils.selectWithJQuery(elements, ".tobago-treeMenuNode-markup-folder .tobago-treeMenuNode-toggle")
.parent().each(function () {
// if there is no command, than the whole node element should be the toggle
var toggle = jQuery(this).children(".tobago-treeMenuCommand").length === 0
? jQuery(this)
: jQuery(this).find(".tobago-treeMenuNode-toggle");
toggle.click(function (event) {
Tree.toggleNode(jQuery(this), event);
});
});
// normal hover effect (not possible with CSS in IE 6)
Tobago4Utils.selectWithJQuery(elements, ".tobago-treeMenuNode").hover(function () {
jQuery(this).toggleClass("tobago-treeMenuNode-markup-hover");
});
// selected for treeNode
Tobago4Utils.selectWithJQuery(elements, ".tobago-treeCommand").focus(function () {
var command = jQuery(this);
var node = command.parent(".tobago-treeNode");
var tree = node.closest(".tobago-tree");
var selected = tree.children(".tobago-tree-selected");
selected.val(Tree.rowIndex(node));
tree.find(".tobago-treeNode").removeClass("tobago-treeNode-markup-selected");
node.addClass("tobago-treeNode-markup-selected");
});
// selected for treeSelect
Tobago4Utils.selectWithJQuery(elements, ".tobago-treeSelect > input").change(function () {
var select = jQuery(this);
var selected = select.prop("checked");
var data = select.closest(".tobago-treeMenu, .tobago-tree, .tobago-sheet");
var hidden = data.children(".tobago-treeMenu-selected, .tobago-tree-selected, .tobago-sheet-selected");
var newValue;
if (select.attr("type") === "radio") {
newValue = "," + Tree.rowIndex(select) + ",";
} else if (selected) {
newValue = hidden.val() + Tree.rowIndex(select) + ",";
} else {
newValue = (hidden.val() as string).replace(new RegExp("," + Tree.rowIndex(select) + ","), ",");
}
// XXX optimize: regexp and Tobago.Tree.rowIndex
hidden.val(newValue);
});
// selected for treeMenuNode
Tobago4Utils.selectWithJQuery(elements, ".tobago-treeMenuCommand").focus(function () {
var command = jQuery(this);
var node = command.parent(".tobago-treeMenuNode");
var tree = node.closest(".tobago-treeMenu");
var selected = tree.children(".tobago-treeMenu-selected");
selected.val(Tree.rowIndex(node));
tree.find(".tobago-treeMenuNode").removeClass("tobago-treeMenuNode-markup-selected");
node.addClass("tobago-treeMenuNode-markup-selected");
});
// init selected field
Tobago4Utils.selectWithJQuery(elements, ".tobago-treeMenu, .tobago-tree, .tobago-sheet").each(function () {
var hidden = jQuery(this).children(".tobago-treeMenu-selected, .tobago-tree-selected, .tobago-sheet-selected");
var string = ",";
jQuery(this).find(".tobago-treeMenuNode-markup-selected, .tobago-treeNode-markup-selected").each(function () {
string += Tree.rowIndex(jQuery(this)) + ",";
});
hidden.val(string);
});
// init expanded field
Tobago4Utils.selectWithJQuery(elements, ".tobago-treeMenu, .tobago-tree, .tobago-sheet").each(function () {
var hidden = jQuery(this).children(".tobago-treeMenu-expanded, .tobago-tree-expanded, .tobago-sheet-expanded");
var string = ",";
jQuery(this).find(".tobago-treeMenuNode-markup-expanded, .tobago-treeNode-markup-expanded").each(function () {
string += Tree.rowIndex(jQuery(this)) + ",";
});
hidden.val(string);
});
// init tree selection for multiCascade
Tobago4Utils.selectWithJQuery(elements, ".tobago-tree[data-tobago-selectable=multiCascade]").each(function () {
var tree = jQuery(this);
tree.find("input[type=checkbox]").each(function () {
jQuery(this).change(function (event) {
var node = jQuery(event.target).parents(".tobago-treeNode");
var checked = node.find("input[type=checkbox]").prop("checked");
var children = Tree.findChildren(node);
children.each(function () {
var childsCheckbox = jQuery(this).find("input[type=checkbox]");
childsCheckbox.prop("checked", checked);
childsCheckbox.change();
});
});
});
});
};
static isExpanded = function (node, expanded) {
var rowIndex = Tree.rowIndex(node);
return expanded.val().indexOf("," + rowIndex + ",") > -1;
};
static rowIndex = function (node) {
return node.attr("id").replace(/.+\:(\d+)(\:\w+)+/, '$1');
};
static findChildren = function (node) {
var treeParentSelector = "[data-tobago-tree-parent='" + node.attr("id") + "']";
var children;
if (Tree.isInSheet(node)) {
children = node.parent("td").parent("tr").nextAll().children().children(treeParentSelector);
} else { // normal tree
children = node.nextAll(treeParentSelector);
}
return children;
};
static isInSheet = function (node) {
return node.parent("td").length === 1;
};
}
Listener.register(Tree.init, Phase.DOCUMENT_READY);
Listener.register(Tree.init, Phase.AFTER_UPDATE);
class TreeListbox {
static init = function (elements) {
elements = elements.jQuery ? elements : jQuery(elements); // fixme jQuery -> ES5
var treeListbox = Tobago4Utils.selectWithJQuery(elements, ".tobago-treeListbox");
// hide select tags for level > root
treeListbox.children().find("select:not(:first)").hide();
var listboxSelects = treeListbox.find("select");
listboxSelects.children("option").each(TreeListbox.initNextLevel);
listboxSelects.each(TreeListbox.initListeners);
};
// find all option tags and add the dedicated select tag in its data section.
static initNextLevel = function () {
var option = jQuery(this);
var select = option.closest(".tobago-treeListbox-level").next()
.find("[data-tobago-tree-parent='" + option.attr("id") + "']");
if (select.length == 1) {
option.data("tobago-select", select);
} else {
var empty = option.closest(".tobago-treeListbox-level").next().children(":first");
option.data("tobago-select", empty);
}
};
// add on change on all select tag, all options that are not selected hide there dedicated
// select tag, and the selected option show its dedicated select tag.
static initListeners = function () {
jQuery(this).change(TreeListbox.onChange);
jQuery(this).focus(function () {
jQuery(this).change();
});
};
static onChange = function () {
var listbox = jQuery(this);
listbox.children("option:not(:selected)").each(function () {
jQuery(this).data("tobago-select").hide();
});
listbox.children("option:selected").each(function () {
jQuery(this).data("tobago-select").show();
});
TreeListbox.setSelected(listbox);
// Deeper level (2nd and later) should only show the empty select tag.
// The first child is the empty selection.
listbox.parent().nextAll(":not(:first)").each(function () {
jQuery(this).children(":not(:first)").hide();
jQuery(this).children(":first").show();
});
};
static setSelected = function (listbox) {
var hidden = listbox.closest(".tobago-treeListbox").children("[data-tobago-selection-mode]");
if (hidden.length == 1) {
var selectedValue = ";";
listbox.children("option:selected").each(function () {
selectedValue += jQuery(this).attr("id") + ";";
});
hidden.val(selectedValue);
}
};
}
Listener.register(TreeListbox.init, Phase.DOCUMENT_READY);
Listener.register(TreeListbox.init, Phase.AFTER_UPDATE);