Implementação de Pesquisa Assíncrona com jQuery zTree para Nós Folha

Este guia técnico demonstra como configurar uma pesquisa assíncrona em uma estrutura de árvore utilizando jQuery zTree, com foco na localização de nós folha. A solução envolve integração entre front-end em JavaScript/JQuery e back-end em Java com Spring MVC.

Configuração do Front-end

O código HTML e JavaScript abaixo ilustra a inicialização da árvore com carregamneto assíncrono e a implementação da funcionalidade de pesquisa. Os parâmetros de busca são transmitidos ao servidor via requisições AJAX.

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<link rel="stylesheet" href="resources/zTreeStyle/zTreeStyle.css" type="text/css">
<link rel="stylesheet" type="text/css" href="resources/bootstrap/bootstrap.min.css">
<title>Exemplo de Árvore Assíncrona</title>
</head>
<body>
    <div class="container">
        <h4>Demonstração de Carregamento Assíncrono com Ztree</h4>
        <input type="text" id="campoBusca" /> &nbsp; <input type="button" id="btnBuscar" value="Pesquisar" onclick="executarPesquisa()"/>
        <ul id="arvoreDados" class="ztree"></ul>
    </div>
</body>
<script src="resources/js/jquery.min.js"></script>
<script type="text/javascript" src="resources/js/jquery.ztree.all.min.js"></script>
<script type="text/javascript" src="resources/js/jquery.ztree.exhide.min.js"></script>
<script type="text/javascript">
var configuracoes = {
    assincrono: {
        ativo: true,
        url: "buscarNos",
        autoParam: ["id", "idPai", "rotulo"],
        filtro: tratarDados
    },
    dados: {
        dadosSimples: {
            ativo: true,
            chaveId: 'id',
            chavePai: 'idPai',
            raizPai: 0
        }
    },
    visual: {
        exibirIcone: false
    },
    callback: {
        aoNoCriado: callbackNoCriado
    }
};

$(document).ready(function(){
    inicializarArvore();
});

function executarPesquisa(){
    var termo = $.trim($("#campoBusca").val());
    var instanciaArvore = $.fn.zTree.getZTreeObj("arvoreDados");
    if(termo !== ""){
        termo = encodeURI(encodeURI(termo));
        instanciaArvore.configuracoes.assincrono.outrosParametros=["param", termo];
    } else {
        instanciaArvore.configuracoes.assincrono.outrosParametros=[];
    }
    instanciaArvore.reAsyncChildNodes(null, "refresh");
}

function callbackNoCriado(evento, idArvore, no){
    var termo = $.trim($("#campoBusca").val());
    var instanciaArvore = $.fn.zTree.getZTreeObj(idArvore);
    if(termo !== "" && no.ehPai){
        instanciaArvore.reAsyncChildNodes(no, "refresh", false);
    }
}

function tratarDados(idArvore, noPai, nosFilhos) {
    return nosFilhos;
}

function inicializarArvore(){
    $.ajax({
        url: "buscarNos",
        type: "post",
        dataType: "json",
        sucesso: function(dados){
            var instanciaArvore = $.fn.zTree.init($("#arvoreDados"), configuracoes, dados);
            var noRaiz = instanciaArvore.getNodeByParam('idPai',0,null);
            instanciaArvore.expandNode(noRaiz, true, false, false, false);
        },
        erro: function(){
            console.error("Falha ao carregar dados iniciais da árvore.");
        }
    });
}
</script>
</html>

Modelo de Dados no Back-end

A classe abaixo representa um nó da árvore, com propriedades para identificação, hierarquia e estado.

package com.exemplo.modelo;

public class NoArvore {
    private String id;
    private String idPai;
    private String nome;
    private String expandido;
    private String possuiFilhos;

    public NoArvore(String id, String idPai, String nome, String expandido, String possuiFilhos) {
        this.id = id;
        this.idPai = idPai;
        this.nome = nome;
        this.expandido = expandido;
        this.possuiFilhos = possuiFilhos;
    }

    // Métodos getters e setters omitidos para brevidade
    public String getId() { return id; }
    public void setId(String id) { this.id = id; }
    public String getIdPai() { return idPai; }
    public void setIdPai(String idPai) { this.idPai = idPai; }
    public String getNome() { return nome; }
    public void setNome(String nome) { this.nome = nome; }
    public String getExpandido() { return expandido; }
    public void setExpandido(String expandido) { this.expandido = expandido; }
    public String getPossuiFilhos() { return possuiFilhos; }
    public void setPossuiFilhos(String possuiFilhos) { this.possuiFilhos = possuiFilhos; }
}

Controlador Spring MVC

O endpoint REST abaixo fornece os nós da árvore de forma assíncrona, simulando uma estrutura hierárquica para demonstração.

package com.exemplo.controlador;

import java.util.ArrayList;
import java.util.List;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import com.exemplo.modelo.NoArvore;

@Controller
public class ControladorArvore {
    @RequestMapping("/buscarNos")
    @ResponseBody
    public List<NoArvore> buscarNos(String id, String idPai, String nome) {
        List<NoArvore> listaNos = new ArrayList<>();
        if(id == null){
            listaNos.add(new NoArvore("1","0","Hardware","false","true"));
            listaNos.add(new NoArvore("2","0","Software","false","true"));
            return listaNos;
        }
        
        switch(id) {
            case "1":
                listaNos.add(new NoArvore("10","1","Placa-mãe","false","true"));
                listaNos.add(new NoArvore("11","1","Memória","false","true"));
                listaNos.add(new NoArvore("12","1","Processador","false","true"));
                break;
            case "2":
                listaNos.add(new NoArvore("20","2","Java","false","true"));
                listaNos.add(new NoArvore("21","2","TypeScript","false","true"));
                listaNos.add(new NoArvore("22","2","Python","false","true"));
                break;
            case "10":
                listaNos.add(new NoArvore("100",id,"Modelo_A","false","true"));
                listaNos.add(new NoArvore("101",id,"Modelo_B","false","false"));
                break;
            case "100":
                listaNos.add(new NoArvore("1000",id,"Versão_1.0","false","false"));
                break;
        }
        
        return listaNos;
    }
}

Princípios de Funcionamento

  • O parâmetro de pesquisa é transmitido ao servidor usando a propriedade outrosParametros do zTree; quando vazio, o array deve ser reinicializado para evitar envio de dados anteriores.
  • No retorno de chamada aoNoCriado, cada nó pai é carregado assincronamente ao ser criado, incorporando o termo de busca para filtragem no servidor.
  • A inicialização da árvore ocorre via carregamento manual do primeiro nível, seguido de expansão programática do nó raiz.
  • A busca efetiva requer que o back-end implemente lógica de filtragem com base no parâmetro param; o exemplo apresentado usa dados estáticos para ilustração.

Tags: jQuery zTree javascript spring-mvc java

Publicado em 6-9 01:22 por Thomas