Esse artigo mostrar como criar um TreeView no Javascript , atualmente estou em um projeto web com json, com isso não posso utilizar componentes do asp.net, sendo assim, estou utilizando muito o Javascript. Tive alguns problemas para criar o treeview como posição da imagens e texto, mas no final ficou muito boa a visualização do TreeView.
Testei o TreeView em 3 browsers (IE, Firefox, Chrome) e funcionou sem problemas. Na figura abaixo mostro as classes utilizadas para construir o TreeView.
Vamos construir o HTML. No evento onload da tag BODY, vamos chamar a função loadTreeView que vai construir o nosso TreeView.
<html>
<head>
<title></title>
<style type="text/css">
</style>
<script language="javascript" type="text/javascript">
</script>
</head>
<body onload="loadTreeView(document.getElementById('contentTreeViewDiv'));">
<div id="contentTreeViewDiv" >
</div>
</body>
</html>
Como disse anteriormente, tive alguns problemas para alinhar imagem e texto no html, como solução coloquei as imagens como background em uma tag LABEL. Nesse momento criaremos os estilos do html.
.fontTree
{
font-family:Segoe UI, Tahoma, Sans-Serif;
font-size:10pt;
color:#1F3870;
}
.nolines_PlusTree
{
background: url(Imagens/nolines_plus.gif) no-repeat left;
}
.nolines_MinusTree
{
background: url(Imagens/nolines_minus.gif) no-repeat left;
}
.joinTree
{
background: url(Imagens/join.gif) no-repeat left;
}
.joinBottomTree
{
background: url(Imagens/joinbottom.gif) no-repeat left;
}
.plusBottomTree
{
background: url(Imagens/plusbottom.gif) no-repeat left;
}
.plusTree
{
background: url(Imagens/plus.gif) no-repeat left;
}
.minusTree
{
background: url(Imagens/minus.gif) no-repeat left;
}
.minusBottomTree
{
background: url(Imagens/minusbottom.gif) no-repeat left;
}
.lineTree
{
background: url(Imagens/line.gif) no-repeat left;
}
Vamor criar a classe treeView e seus métodos e propriedades.
//Classe TreeView
function treeView() {
this.nodeRoot = null;//Tipo itemNode.
}
//Adiciona um nó raiz.
treeView.prototype.addNodeRoot = function (id, name, image, isExpand, link) {
this.nodeRoot = new itemNode(id, name, image, isExpand, link);
return this.nodeRoot;
};
//Limpa o nó raiz.
treeView.prototype.clear = function () {
this.nodeRoot = null;
};
//Retorna o conteúdo html para criar o treeview.
treeView.prototype.contentHtml = function () {
return this.nodeRoot.contentHtml(this.nodeRoot.id, 0, true,
false, false, this.nodeRoot.isExpand, true);
};
Vamor criar a classe itemNode e seus métodos e propriedades.
//classe Nó.
function itemNode(id, name, image, isExpand, link) {
this.id = id;//Identificador do nó
this.name = name; //Texto do nó.
this.image = image;//Imagem do nó
this.isExpand = isExpand;//Indica se o nó é mostrado expandido no momento da criação.
this.link = link;//Indica se o nó vai ser um link.
this.items = [];//Coleção de nós filhos.
}
//Adiciona um nó filho
itemNode.prototype.addNode = function (id, name, image, isExpand, link) {
var obj = new itemNode(id, name, image, isExpand, link);
this.items[this.items.length] = obj;
return obj;
};
//Limpa a coleção de nós filhos.
itemNode.prototype.clear = function () {
this.items = [];
};
//Obtém identificadores dos nós filhos. Utilizado para expandir
e recolher os nós filhos.
itemNode.prototype.getIdChildNodes = function () {
var arrayId = '';
for (var i = 0; i < this.items.length; i++) {
arrayId += this.items[i].id + ';';
}
return arrayId;
}
//Retorna o conteúdo html para criar o treeview.
//<param name="id">Identificador do objeto nó.</param>
//<param name="indent">Identação dos nós.</param>
//<param name="nodeFirst">Indica se o nó é o nó raiz.</param>
//<param name="nodeSingle">Indica se o nó não tem irmãos.</param>
//<param name="isImgLine">Indica se imagem linha será adicionada.
É adiciona quando o pai do nó tem irmão.</param>
//<param name="isExpand">Indica se o nó vai estar expandido no
momento da criação.</param>
//<param name="parentNodeSingle">Indica se o pai do nó não tem
irmãos. Isso indica para a funão adicionar ou não a imagem linha</param>
itemNode.prototype.contentHtml = function (id, indent, nodeFirst,
nodeSingle, isImgLine, isExpand, parentNodeSingle) {
var content = '';
var strIndent = '';
for (var i = 0; i < indent; i++) {
strIndent += ' ';
}
var className = '';
var lineImg = '';
var addImgLine = false;
if (!nodeFirst && !nodeSingle) {
addImgLine = true;
}
if (nodeFirst) {
if (!isExpand) {
className = 'nolines_PlusTree';
}
else {
className = 'nolines_MinusTree';
}
nodeFirst = false;
}
else {
if (nodeSingle) {
if (this.items.length == 0) {
className = 'joinBottomTree';
}
else {
if (!isExpand) {
className = 'plusBottomTree';
}
else {
className = 'minusBottomTree';
}
}
}
else {
if (this.items.length == 0) {
className = 'joinTree';
}
else {
if (!isExpand) {
className = 'plusTree';
}
else {
className = 'minusTree';
}
}
}
}
var eventClick = '';
if (this.items.length > 0) {
var arrayId = this.getIdChildNodes();
eventClick = 'onclick="nodeExpand(document.getElementById(\''
+ id + '\'), \'' + arrayId + '\')"';
}
content += '<div id="' + id + '" style="display:@visible@;">
<input id="' + id + 'Hidden" type="hidden" value="'
+ (isExpand ? '1' : '0') + '" />';
var valueNode = '';
var valueLink = '';
if (this.link != null && this.link != '') {
valueLink = '<a class="fontTree" href="' + this.link + '">'
+ this.name + '</a>';
}
else {
valueLink = this.name;
}
if (this.image != null && this.image != '') {
valueNode = '<label class="fontTree" style="background: url('
+ this.image + ') no-repeat left;"> ' + valueLink + '</label>';
}
else {
valueNode = '<label class="fontTree">' + valueLink
+ '</label>';
}
if (isImgLine) {
var strIndentLine = '';
for (var i = 0; i < indent - 1; i++) {
if (i == indent - 2 && parentNodeSingle) {
strIndentLine += ' <label> </label>';
}
else {
strIndentLine += ' <label class="lineTree">
</label>';
}
}
content += strIndentLine + ' <label id="' + id
+ 'ClassNameHidden" class="' + className + '" ' + eventClick
+ '> </label>' + valueNode + '<br>';
addImgLine = true;
}
else {
content += strIndent + '<label id="' + id
+ 'ClassNameHidden" class="' + className + '" '
+ eventClick + '> </label>' + valueNode + '<br>';
}
var newindent = indent + 1;
for (var i = 0; i < this.items.length; i++) {
var isNodeSingle = false;
var strValue = '';
if (i == this.items.length - 1) {
isNodeSingle = true;
}
strValue = this.items[i].contentHtml(this.items[i].id,
newindent, nodeFirst, isNodeSingle, addImgLine,
(!isExpand ? false : this.items[i].isExpand), nodeSingle);
if (isExpand) {
strValue = strValue.replace('@visible@', 'block');
}
else {
strValue = strValue.replace('@visible@', 'none');
}
content += strValue;
}
content += '</div>';
return content;
};
Utilizamos recursividade para montar o TreeView, cada nó pode ter filhos e irmãos.
Agora vamos criar a função que vai expandir e recolher os nós. Na função contentHtml verificamos se o nó tem filhos ou não, caso o nó é pai de outros nós adicionamos essa função no evento onclick da tag LABEL.
//Expandi ou recolhe os filhos do nó.
//<param name="objDiv">Div que o nó e os nós filhos estão dentro.
</param>
//<param name="ids">Todos os identificadores dos nós filhos,
utilizamos para expandir ou recolher eles. </param>
function nodeExpand(objDiv, ids) {
var arrayId = ids.split(';');
var display = '';
var objHidden = document.getElementById(objDiv.id + 'Hidden');
var objLabel = document.getElementById(objDiv.id + 'ClassNameHidden');
if (objLabel.className == 'nolines_PlusTree' ||
objLabel.className == 'nolines_MinusTree') {
if (objLabel.className == 'nolines_PlusTree') {
objLabel.className = 'nolines_MinusTree';
}
else {
objLabel.className = 'nolines_PlusTree';
}
}
else if (objLabel.className == 'plusBottomTree' ||
objLabel.className == 'minusBottomTree') {
if (objLabel.className == 'plusBottomTree') {
objLabel.className = 'minusBottomTree';
}
else {
objLabel.className = 'plusBottomTree';
}
}
else if (objLabel.className == 'plusTree' ||
objLabel.className == 'minusTree') {
if (objLabel.className == 'plusTree') {
objLabel.className = 'minusTree';
}
else {
objLabel.className = 'plusTree';
}
}
if (objHidden.value == '0') {
display = 'block';
objHidden.value = '1';
}
else {
display = 'none';
objHidden.value = '0';
}
for (var i = 0; i < arrayId.length - 1; i++) {
var objNode = document.getElementById(arrayId[i]);
objNode.style.display = display;
}
}
Próxima função foi criada para montar o TreeView.
function loadTreeView(objContent) {
objTreeView = new treeView();
var objRoot = objTreeView.addNodeRoot(0, 'Node Raiz', 'Imagens/globe.gif', true);
objRoot.addNode(1, 'Node 1', 'Imagens/page.gif', false);
var objChild2 = objRoot.addNode(2, 'Node 2', 'Imagens/base.gif', false);
var objChild3 = objChild2.addNode(3, 'Node 3', 'Imagens/base.gif', false,
'http://www.uol.com.br');
var objChild4 = objChild3.addNode(4, 'Node 4', 'Imagens/base.gif', false);
objChild4.addNode(5, 'Node 5', 'Imagens/page.gif', false);
objChild2.addNode(6, 'Node 6', 'Imagens/page.gif', false);
var objChil4 = objRoot.addNode(7, 'Node 7', 'Imagens/base.gif', false);
objChil4.addNode(8, 'Node 8', 'Imagens/page.gif', false);
objRoot.addNode(9, 'Node 9', 'Imagens/page.gif', false);
objContent.innerHTML = objTreeView.contentHtml();
}
Abaixo a visualização do TreeView no browser.