module ExpressTemplates
module Components
module Presenters
#
# Create an html table or ol (ordered list) for
# a model object representing a tree of similar objects.
#
# The objects must respond to :children.
#
# The block is passed a NodeBuilder which may accept field names.
#
# Example:
#
# ```ruby
# tree_for(:roles) { |role|
# role.name
# }
# ```
#
# If the view has an @roles variable with a Role having children,
# this will turn into markup such as the following:
#
#
# - SuperAdmin
#
# - Admin
#
# - Publisher
#
#
# - Auditor
#
#
#
#
#
#
class TreeFor < Configurable
tag :ul
has_attributes :class => 'tree'
has_option :root, "Root of the tree. Defaults to collection with the same as the id.", type: :proc
contains -> (&customize_block) {
@customize_block = customize_block
list_items(root_node)
}
before_build -> {
add_class config[:id]
}
def root_node
if config[:root] && config[:root].respond_to?(:call)
config[:root].call
else
send(config[:id])
end
end
def list_items(nodes)
nodes.each do |node|
list_item(node)
end
end
def list_item(node)
li {
if @customize_block
@customize_block.call(node)
else
text_node "#{node.name}#{"\n" if node.children.any?}"
end
if node.children.any?
ul {
list_items(node.children)
}
end
}
end
end
end
end
end