Generate a simple tree-menu in Grails

It's seems one of the many posts you can find in internet that helps you to generate a tree-menu using javascript/java/... What I want to illustrate is a method that use recursion in back-end (java code that generate the Tree structure) and front-end (a gsp that shown the tree calling itself!!).



In fact, the start point, is that our page is not a "simple" page but is written as grails templates.

Template is a grails way to get your front-end code structured and provide an highly re-usable mechanism that you can call simply using a defined taglib.



class TreeMenu {



def addNode = {nodeElement, machine, tagList ->

def nodes = [:]

nodes[machine.hostName] = machine

def newList = tagList - nodeElement

newList?.each {currentTag ->

nodes[currentTag.name] = addNode(currentTag, machine, newList)

}



nodes

}

}



Is an extraction of my program codes... in the original version the data structure is not a simple Map but I've a complex object, so I can do, for example, a check if there is a node with current provided name and so on.

What this code try to do, is to add a Machine to each Tree-Tag I'm sending to function as a List.

"nodeName" is the current node where I want my machine

"machine" is the object name I want in my tree

"tagList" is the list of all tree-node where my machine will be put



For example, I could have this situation



machine: "TryMachine"

tagList: ["A", "B"]



TreeMenu.addNode("Root", machine, tagList)



The result of this method invokation will be:

 Root 

|-> A

| |->B

| | |TryMachine

| |TryMachine

|-> B

| |TryMachine

| |-> A

| | |TryMachine

| TryMachine



Display the tree

The extraordinary feature offers by grails is, as I said, the usage of recursion on the front-end, that make you able to create a page without insertion of some java codes: all just with default grails taglibs.

Here an example gets from my code:

<g:each in="${nodes}" var="element">

<g:if test="${element.value instanceof Machine}">

${element.name}

</g:if>

<g:else>

<g:machineList template="/templates/machineTree" data="${element}"/>

</g:else>

</g:each>



And in your page, where you want to put your tree, you can just simply call the template:

<g:machineList template="/templates/machineTree" data="${treeData}"/>



Is a just a simple example (and, in fact, I'm not sure that with mods I've done to create this post, all work well :P), If you want you can make some improvements to this code, attaching, for example, javascript functions to get your tree-node opened and closed, or some other kinds of object type.u