Question

I have a table in database like this:

id   -   title   -  parentID
-----------------------------
1        Root          null
2        item 1        1
3        item 2        1
4        item 3        1
5        item 3.1      4

this should create something like this:

--Root
----item 1
----item 2
----item 3
-------item 3.1

here's my controller to fetch the root node and its children:

@RequestMapping(value="/CourtBranch/LoadTreeView", method = RequestMethod.GET)
    public void LoadList(@RequestParam("ParentId") String parentID,HttpServletRequest req, HttpServletResponse resp) {
        List lst;
        if (parentID.equals("Root"))
        {
            lst = _COURTBRANCH.LoadTreeChildren(null, "Root");   // selects records which have parent=null
        }
        else
        {
            lst = _COURTBRANCH.LoadTreeChildren(parentID, "TreeNode");   // selects records which have parent=parentID
        }

        resp.setContentType("application/json");
        resp.setCharacterEncoding("utf-8");
        try {
            resp.getWriter().print(_gson.toJson(lst));
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

and this script loads my root:

<script type="text/javascript">
  $(function(){
    $("#tree").dynatree({
          initAjax: {
              url: "/CourtBranch/LoadTreeView.json?ParentId=Root",
              data: { mode: "funnyMode" }
              },
      onActivate: function(node) {
        $("#echoActive").text(node.data.title);
      },
      onDeactivate: function(node) {
        $("#echoActive").text("-");
      }
    });
  });
</script>

now I need to know how to send the root's id to my controller to fetch root's children and add them to the root node. should I use appendAjax function? how?

Was it helpful?

Solution

Basically you don't really want to do that straight into your controller. (loose coupling)

I'd create 2 utils classes Tree<T> and Node<T> to manage your tree and nodes:

Here is the tree class:

public class Tree<T> {

    private Node<T> rootElement;

    public Tree() {
        super();
    }

    public Node<T> getRootElement() {
        return this.rootElement;
    }

    public void setRootElement(final Node<T> rootElement) {
        this.rootElement = rootElement;
    }

    public List<Node<T>> toList() {
        final List<Node<T>> list = new ArrayList<Node<T>>();
        walk(this.rootElement, list);
        return list;
    }

    private void walk(final Node<T> element, final List<Node<T>> list) {
        list.add(element);
        for (final Node<T> data : element.getChildren()) {
            walk(data, list);
        }
    }
}

And the node class with some helper methods

public class Node<T> {

    private T data;
    private List<Node<T>> children;

    public Node() {
        super();
    }

    public Node(final T data) {
        this();
        setData(data);
    }

    public Boolean hasChildren() {
        return this.children.size() != 0;
    }

    public List<Node<T>> getChildren() {
        if (this.children == null) {
            return new ArrayList<Node<T>>();
        }
        return this.children;
    }

    public void setChildren(final List<Node<T>> children) {
        this.children = children;
    }

    public int getNumberOfChildren() {
        return this.children.size();
    }

    public void addChild(final Node<T> child) {
        if (this.children == null) {
            this.children = new ArrayList<Node<T>>();
        }
        this.children.add(child);
    }

    public void insertChildAt(final int index, final Node<T> child) throws IndexOutOfBoundsException {
        if (index == getNumberOfChildren()) {
            addChild(child);
            return;
        } else {
            this.children.get(index);
            this.children.add(index, child);
        }
    }

    public void removeChildAt(final int index) throws IndexOutOfBoundsException {
        this.children.remove(index);
    }

    public T getData() {
        return this.data;
    }

    public void setData(final T data) {
        this.data = data;
    }
}

Then I'd have your type of tree extending the tree. based on your controller CourtBranch

Suppose your CourtBranch model has the following structure (I'm using hibernate + jpa):

@Entity
@Table
public class CourtBranch

private String id;
private String name;
private Long partentId;

//getters setters etc...

Create a class that extends the Tree:

public class CourtBranchTree extends Tree<CourtBranch>
    public CourtBranchTree{
        super();
    }

Now create your TreeGridResponse class:

public class TreeGridResponse {
    //inject the service to get the id of your model
    @Resource
    CourtBranchService cbService;
    //if you are using a repository for the db queries:
    @Resource
    CourtBranchRepository cbRepo;

    public TreeGridResponse(){
    }

    //returning the tree as a JSON to use AJAX
    public String cbBTreeAsJson(final CourtBranchTree tree){
        final StringBuffer sb = new StringBuffer();
        final CourtBranch root = tree.getRootElement().getData();
        sb.append("[\r {\"title\": \"" + root.getName() + "\", \"key\": \"" + root.getId() + "\", \"children\": [\r");
        final List<Node<CourtBranch>> children = tree.getRootElement().getChildren();
        loopforChildre(sb, children);
        sb.append("]");
        return sb.toString();
    }

    private StringBuffer loopForChildren(final StringBuffer sb, final List<Node<UserRight>> children) {
        for (int i = 0; i < children.size(); i++) {
            final Node<courtBranch> childElement = children.get(i);
            if (i == 0) {
                sb.append("{\"title\": \"" + childElement.getData().getName() + "\", \"key\": \"" + childElement.getData().getId() + "\"");
            } else {
                sb.append(", {\"title\": \"" + childElement.getData().getName() + "\", \"key\": \"" + childElement.getData().getId() + "\"");
            }
            if (childElement.hasChildren()) {
                sb.append(", \"children\": [\r");
                loopForChildren(sb, childElement.getChildren());
            } else {
                sb.append("}");
            }
        }
        sb.append("]}");
        return sb;
    }

    public CourtBranchTree get() {
        final CourtBranchTreetree tree = new CourtBranchTree();
        final Node<CourtBranch> root = new Node<CourtBranch> (this.cbRepo.findOne(Long.valueOf(1)));//gets your root
        getRecursive(root, tree);
        tree.setRootElement(root);
        return tree;
    }

    private void getRecursive(final Node<CourtBranch> courtBranch, final CourtBranchTree tree) {
        final List<CourtBranch> children = this.cbService.findCourtBranchByParentId(courtBranch.getData().getId());
        final List<Node<CourtBranch>> childElements = new ArrayList<Node<CourtBranch>>();
        for (final CourtBranch childCourtBranch : children) {
            final Node<CourtBranch> childElement = new Node<CourtBranch>(childUserRight);
            childElements.add(childElement);
            getRecursive(childElement, tree);
        }
        courtBranch.setChildren(childElements);
    }
}

Register the TreeGridResponse in your config to get the bean and inject it into your controller.

@Controller
public class CBController

@Resource
private TreeGridResponse gridResponse;

@RequestMapping(value="/CourtBranch/LoadTreeView", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
@ResponseBody
public String cbTree() {
    return this.gridResponse.cbBTreeAsJson(this.gridResponse.get());
}

Note the @ResponseBody annotation that will indicate Spring to parse your string into JSON so that your AJAX can read it.

And your jsp:

<div id ="cbTree"></div>
<script type ="text/javascript">
    $(function(){
    $("#cbTree").dynatree({
        initAjax:{
            url: /CourtBranch/LoadTreeView
            },
        checkbox: true,
        selectMode: 3
    });
    });
</script>

Hope this helped...

OTHER TIPS

I did exactly as Francois said and it worked! thanks..Just minor changes since for some reason my JSON wasnt being parsed. I am not putting out MyTree.java and MyNode.java as they are very basic simple classes.

public class MYDocTreeManager {

private MYTree MYTree = new MYTree();

private String sDir = "C:\\Users\\sandeepraj.tandon\\Documents\\DynaTreeFolder";


public void buildMYTree(){


    System.out.println("Top Level Starts");
    File[] faFiles = new File(sDir).listFiles();
     int key = 1;
      for(File file: faFiles){
          MYNode MYNode = new MYNode();
          MYNode.setTitle(file.getName());
          MYNode.setTooltip(file.getName());
          MYNode.setKey(String.valueOf(key));
          MYTree.addNode(MYNode);         

        if(file.getName().matches("^(.*?)")){
          System.out.println(file.getName()+" is a file at top level");
        }
        if(file.isDirectory()){
            MYNode.isFolder(true);              



          //System.out.println(file.getAbsolutePath()+"is a directory at top level");
          //String treeJson = file.getAbsolutePath()+"is a directory at top level";
          addChildToNodeRec(MYNode,file.getAbsolutePath(), key);
        }

        key++;


      }

}


private void addChildToNodeRec(MYNode MYNode,String currDirPath, int key){

    System.out.println("Scanning under "+MYNode.getTitle());
    int childKey = 1;
    File[] faFiles = new File(currDirPath).listFiles();
    for(File file: faFiles){
        MYNode childNode = new MYNode();
        childNode.setTitle(file.getName());

        MYNode.setKey(String.valueOf(key)+"."+childKey);
        MYNode.addChild(childNode);
        if(file.getName().matches("^(.*?)")){

            System.out.println("Found a document "+file.getName());
        }
        if(file.isDirectory()){             
            System.out.println("Found a directory "+file.getName());
            MYNode.isFolder(true);
            addChildToNodeRec(childNode,file.getAbsolutePath(), childKey);
        }   

        childKey++;

      }


}


/**
 * Get the JSON object for the tree built
 * @return
 */
 public String treeToJason() {
     StringBuffer json =new StringBuffer();
     json.append("[\r");
     int topNodeCount = 0;
    for (MYNode topNode:MYTree.getTopLevelNodes()){
        //System.out.println("topNode title :"+topNode.getTitle());
        //json = json.append("topNode title :"+topNode.getTitle()+"\n");
        if(topNodeCount==0){
            json.append("{\"title\": \"" + topNode.getTitle() + "\", \"key\": \"" + topNode.getKey() + "\", \"children\": [\r");
        } else {
            json.append(", \n {\"title\": \"" + topNode.getTitle() + "\", \"key\": \"" + topNode.getKey() + "\", \"children\": [\r");
        }
        //json = json.append("topNode title :"+topNode.getTitle()+"\n");
        childNodeJson(json, topNode);

        topNodeCount++;
    }

          json.append("]");
     return json.toString();
     //   return MYTree.toJson(MYTree);
 }


private void childNodeJson(StringBuffer json, MYNode node) {
    int childCount = 0;
    for (MYNode child : node.getChildren()){

        //System.out.println("Child No."+childCount+" of "+topNode.getTitle()+" is :"+child.getTitle()+"\n");   
        //json.append("Child No."+childCount+" of "+topNode.getTitle()+" is :"+child.getTitle()+"\n");
         if (childCount == 0) {
                json.append("\t\t");
                json.append("{\"title\": \"" + child.getTitle() + "\", \"key\": \"" + child.getKey() + "\"");
         } else {

                json.append(",");
                json.append("\n\t\t");
                json.append("{\"title\": \"" + child.getTitle() + "\", \"key\": \"" + child.getKey() + "\"");
         }
        if(child.getChildren().size()>0){
            json.append(",\"children\": [\r");
            childNodeJson(json, child);
        } else {
            json.append("}");
        }
        childCount++;
    }

     json.append("\n\t\t]}");



}

 public static void main(String args[]){


     MYDocTreeManager MYDocTreeManager  = new MYDocTreeManager();
     MYDocTreeManager.buildMYTree();
     System.out.println(MYDocTreeManager.treeToJason());
 }

}

Changed my implementation as discussed here https://stackoverflow.com/a/35608588/5436115

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top