4

I'm trying to implement the FuelUX tree plugin and I've followed the example so far but I need a nested structure. I'm assuming the tree plugin is capable of handling nested children? is this correct?

  var treeDataSource = new TreeDataSource({
     data: [
        { name: 'Test Folder 1', type: 'folder', additionalParameters: { id: 'F1' },
          data: [
            { name: 'Test Sub Folder 1', type: 'folder', additionalParameters: { id: 'FF1' } },
            { name: 'Test Sub Folder 2', type: 'folder', additionalParameters: { id: 'FF2' } },
            { name: 'Test Item 2 in Folder 1', type: 'item', additionalParameters: { id: 'FI2' } }
          ]
        },
        { name: 'Test Folder 2', type: 'folder', additionalParameters: { id: 'F2' } },
        { name: 'Test Item 1', type: 'item', additionalParameters: { id: 'I1' } },
        { name: 'Test Item 2', type: 'item', additionalParameters: { id: 'I2' } }
      ],
  delay: 400
});

So far it seems to load the top level items into the opened folders rather than the nested data items. This is what the demo on their site also does but this doesn't seem as if its the desired interaction. Can anyone confirm if this is expected behaviour?

Can anyone point me to code where they've created a nested data tree using this plugin? Is there something really obvious I am missing?

madth3
  • 7,275
  • 12
  • 50
  • 74
tiny_m
  • 263
  • 1
  • 3
  • 9

3 Answers3

2

I am actually in the process of writing a blog post on this very issue.

The solution I have developed is not for the faint-of-heart. The problem is that the folder objects do not support instantiation with child data. Also, adding children is no trivial task. I spun up a quick fiddle that you can pick through to get an idea of how to accomplish your goal. I am using this same solution only that my addChildren function calls out to an MVC route via AJAX and gets back a JSON object to populate the children dynamically.

You can literally, copy and paste the code from my fiddle and start using the addChildren function out-of-the-box.

Joe
  • 6,401
  • 3
  • 28
  • 32
  • 1
    Thanks Joe! I like your approach for just-in-time population of the folder items as the folder is being opened. If you needed to do this asynchronously you could modify http://www.bootply.com/64521 to go and get some data before calling the callback. – Adam Alexander Jun 17 '13 at 12:59
  • @AdamAlexander Yes, in my production code I am calling out to an MVC WebAPI Route via AJAX and getting back a serialized data set for populating the child nodes (folders and items) on open. :) – Joe Jun 17 '13 at 13:22
  • 1
    @joe Any update on that blog post? Would love to read it, and would also love to see the MVC example since it's exactly what I am trying to accomplish at the moment. – Kyle Jun 27 '13 at 22:54
1

I'm sorry for the lack of documentation about this - it needs to be improved for sure.

The idea is that you provide a dataSource when instantiating the tree control, and that data source should have a data function with the signature (options, callback). That data function will be called on control init to populate the root level data, and will be called again any time a folder is clicked.

The job of the data function is to look at the options parameter which is populated from the jQuery.data() on the clicked folder and respond with the data for that folder. The special case is the initial root folder data, where the options are populated from any jQuery.data() on the control's root div, which may or may not exist.

The jQuery.data() on folders is populated from the array of objects you provide in your data function's callback. You can see in this example https://github.com/ExactTarget/fuelux/blob/master/index.html#L184-L189 there is a property called additionalParameters but really you can provide any additional properties beyond the required name and type for you to use later (the next time your data function is called) to determine which folder was clicked and return the data for that folder.

Our current example returns the same static data for every folder, which is not the best example, so I do hope to improve this situation by either creating a tutorial myself or linking to one if someone beats me to it.

Adam Alexander
  • 15,132
  • 5
  • 42
  • 41
1

Following up on Adam's answer, here is an example that seems to accomplish what you want..

The data function for the DataSource can check to see if there is "sub" data passed via options:

DataSource.prototype = {

    columns: function () {
        return this._columns;
    },

    data: function (options, callback) {

        var self = this;
        if (options.search) {
            callback({ data: self._data, start: start, end: end, count: count, pages: pages, page: page });
        } else if (options.data) {
            callback({ data: options.data, start: 0, end: 0, count: 0, pages: 0, page: 0 });
        } else {
            callback({ data: self._data, start: 0, end: 0, count: 0, pages: 0, page: 0 });
        }
    }
};

Demo on Bootply: http://www.bootply.com/60761

Carol Skelly
  • 351,302
  • 90
  • 710
  • 624
  • 1
    Very nice and clean approach! I clarified the solution a little by removing some of the parts of the datasource that only apply to the datagrid, and by adding an empty data array to empty folders so that the folders wouldn't keep expanding forever. Modifications here: http://www.bootply.com/64521 – Adam Alexander Jun 17 '13 at 12:56
  • This will end up being the official recommendation for a static tree where the items are known ahead of time. Thanks for taking the time to work this out. – Adam Alexander Jun 17 '13 at 12:57