Rhywden
Rhywden

Reputation: 750

How to create a directory-like structure with meteor templates?

Consider this mockup of my intended output:

Intended structure

The data structure behind this in a Mongo DB looks like this - I did not nest the subcategories inside the document because I still want to be able to update subdocuments atomically - and I also want to allow a dynamic amount of layers below. From what I've seen, Mongo currently does not allow for easy, dynamic access of nested documents.

topmost_category = {
  _id : "foo",
  category_name : "Example",
  parent_category: null,
  subcatories: [ "sub_foo1", "sub_foo2", ... ]
}

child_category = {
  _id = "sub_foo1",
  category_name : "Example 2",
  parent_category: "foo",
  subcategories: []
}

The underlying HTML consists simply of nested -branches. The currently selected category gets an "active" class, and the icons in front are named "icon-folder-close" and "icon-folder-open" (<i class="icon-folder-close"></i>).

Now, I could use the answer to this to create a complete tree-like structure. However, all the branches would be "open". How do I make it so that only the currently selected branch is visible like shown in my mockup (and still have it reactive to boot)?

Upvotes: 3

Views: 1257

Answers (2)

gadicc
gadicc

Reputation: 1461

You can see the implementation of a very similar approach to that described by Hubert here:

http://www.meteorpedia.com/read/Trees

It's the code to the (working) category browser functionality of the wiki (you can see a demo there).

The main difference to Hubert's answer is that it uses a publish/subscribe with a session variable to fetch the data of opened children in real time.

Upvotes: 2

Hubert OG
Hubert OG

Reputation: 19544

The easiest way would be to add a boolean flag for branches denoting whether or not they belong to current path, and therefore should be open.

 

<template name="branch">

    {{#if open}}
        <div class="openBranch">
            ...
            {{#each children}}
                ...
            {{/each
        </div>
    {{else}}
        <div class="closedBranch">
            ...
        </div>
    {{/if}}

</template>

 

Now, the setting and management of this flag depends on the logic of your application. Where do you store the currently selected branch?

 

I assume the state is limited to a single client. In this case, one solution is to:

  • maintain an array of opened branches ids, scoped to a single file,
  • implement the open flag as a helper:

 

Template.branch.open = function() {
    return _.indexOf(openedBranches, this._id) !== -1;
}

 

  • when user changes selection, clear the array and populate it with path from the selected branch to the top.

 

Upvotes: 1

Related Questions