segunda-feira, 24 de agosto de 2009

JSP e Oracle - Para apresentar uma Treeview

Olá pessoal!

Dando manutenção em um sistema java web com interface jsp precisei usar uma treeview para apresentar as categorias de produtos para o usuário. Vou relatar aqui a experiência.


As categorias estão modeladas no banco em uma tabela com autorelacionamento.



No oracle para consultar uma table com autorelacionamento podemos utilizar a seguinte query:


select id, LEVEL, SYS_CONNECT_BY_PATH(nome, '@') as caminho
from categoria CONNECT BY parent_id = PRIOR id START WITH id = categoria_inicial


A categoria_inicial é a primeira categoria de uma árvore, nesse sistemas existem várias árvores de categorias.

O resultado fica assim para a categoria_inicial igual a 30:

id level caminho
30 1 @Material de escritório
31 2 @Material de escritório@Informática
34 3 @Material de escritório@Informática@Tinta
55 4 @Material de escritório@Informática@Tinta@Tinta Impressoras
60 3 @Material de escritório@Informática@Armazenamento
63 4 @Material de escritório@Informática@Armazenamento@DAT/DLT/DVD/DDS
64 4 @Material de escritório@Informática@Armazenamento@Disquetes
92 3 @Material de escritório@Informática@Teste
93 4 @Material de escritório@Informática@Teste@Teste1
113 4 @Material de escritório@Informática@Teste@Teste2
120 4 @Material de escritório@Informática@Teste@Test3

Ai no java criei uma classe para representar a estrutura da categoria, ficou assim:

public class CategoriaTreeView {
public String id;
public int level;
public String path;

public CategoriaTreeView(String id, int level, String path){
this.id = id;
this.level = level;
this.path = path;
}
}


Como essa classe vai ser utilizada somente como uma estrutura de dados para representar o dado que será exibido na tela ela não tem gets e sets. Nem toda classe java precisa ter gets e sets. Gets e sets aqui são desnecessários e não acresentam nada. Acredite. Mas isso é assunto para outro post.

Também tenho um DAO que acessa o banco e entrega um List com os objetos CategoriaTreeView.

Antes disso fiz uma pesquisa na internet sobre como criar uma treeview no jsp (ou html) e encontrei o jQuery plugin: Treeview que transforma uma lista não ordenada do html <ul> em uma árvore.

Agora o problema é transformar a minha coleção de CategoriaTreeView em uma lista não ordenada com <ul> e <li>. Para isso eu criei a seguinte função recursiva que retorna uma String que será utilizada dentro do html:


private String processa(int atual, List<CategoriaTreeView> lista){
if(lista == null) return "";
String out = "";
if(lista.size() == 0) {
if(atual > 0){
out += "</li>\n";
out += "</ul>\n";
out += processa(atual - 1, lista);
}
}else if(lista.size()>0){
CategoriaTreeView item = lista.remove(0);
if(item.level == atual){
out += "</li>\n";
out += "<li><span>" + subString(item.level, item.path) + "</span>\n";
out += processa(item.level, lista);
}else if(item.level > atual){
out += "<ul>\n";
out += "<li><span>" + subString(item.level, item.path) + "</span>\n";
out += processa(item.level, lista);
}else if(item.level < atual){
out += "</li>\n";
out += "</ul>\n";
// adiciono o cara de volta na lista pois ainda não foi processado. estou voltando um nivel na árvore.
lista.add(0, item);
out += processa(atual - 1, lista);
}
}
return out;
}

Também temos a função para retornar a categoria de dentro do caminho:


private String subString(int i, String s){
String[] ss = s.split("@");
return ss[i];
}


Dentro do meu servlet eu tenho o seguinte código:

ArrayList categorias = dao.categorias(categoria_inicial);
String treeView = processa(0, categorias);
treeView = treeView.replaceFirst("<ul>", "<ul id=\"browser\">");
request.setAttribute("treeView", treeView);

Para exibir a treeview no jsp eu utilizei o exemplo simple.html que vem no download do jQuery plugin: Treeview. A única mudança foi que eu fiz o download do jquery ao invés de usar o link direto do ajax.googleapis.com.

Adicionei o seguinte ao jsp:


<link rel="stylesheet" href="../jquery.treeview.css" />
<link rel="stylesheet" href="../red-treeview.css" />
<link rel="stylesheet" href="screen.css" />

<script type="text/javascript" src="jquery-1.3.2.min.js"></script>
<script src="../lib/jquery.cookie.js" type="text/javascript"></script>
<script src="../jquery.treeview.js" type="text/javascript"></script>

<script type="text/javascript">
$(document).ready(function(){
$("#browser").treeview({control: "#treecontrol", animated:"normal", persist: "cookie"});
});
</script>

<%
String s = (String)request.getAttribute("treeView");
if(s != null && !s.trim().equals("")){
%>
<tr>
<td>
<br>
<div id="treecontrol">
<a title="Collapse the entire tree below" href="#">Fechar Tudo</a>
<a title="Expand the entire tree below" href="#">Abrir Tudo</a>
</div>

</td>
</tr>
<tr>
<td>
<br>
<div><%= s %></div>
</td>
</tr>
<%
}
%>


O resultado fica parecido com esse demo que está no site.



Abraços, Rodrigo Alencar.

Um comentário:

 
BlogBlogs.Com.Br