Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Google Tasks API + FancyTree #431

Closed
maxitromer opened this issue May 7, 2015 · 6 comments
Closed

Google Tasks API + FancyTree #431

maxitromer opened this issue May 7, 2015 · 6 comments
Labels

Comments

@maxitromer
Copy link

Hi,

First I want to tell you that this is the best Tree on internet right now. Thanks for this excelent work.

However ...

I'm working with the Google Tasks API. They return a JSON I cant connect with FancyTree.

This is mi test code:

http://jsfiddle.net/prncw2sL/1/

Google use a "parent" item to know if the task is a children of another task, in this way they create a tree with tasks and sub-tasks.

But in FancyTree you use a "children" inside the task for subtasks.

There is a way I can adapt the FancyTree behave to connect with the Google Tasks API?

Thanks in advance.

@mar10
Copy link
Owner

mar10 commented May 8, 2015

Interesting question, I will look into it. Could you post this on Stackoverflow (and leave a link here), which will make it more accessible to other developers.
Thanks

@maxitromer
Copy link
Author

Just to inform that I find a way and I'm working on it.

I will publish it here when works.

Bests.

@mar10
Copy link
Owner

mar10 commented May 9, 2015

cool. I also played around a bit and came up with this:
the recommended way to tweak input is postProcess. See also the docs

Note that this callback only fires for ajax requests, not if plain objects are passed to source, so it won't work in your fiddle.
This sample also assumes that sub-tasks appear after their parents.

function convertData(childList) {
    var parent,
          nodeMap = {};

    if( childList.kind === "tasks#tasks" ) {
        childList = childList.items;
    }
    return $.map(childList, function(c){
        c.key = c.id;
        delete c.id;
        nodeMap[c.key] = c;
        // Check if c is a child node
        if( c.parent ) {
            // add c to `children`array of parent node
            parent = nodeMap[c.parent];
            if( parent.children ) {
                parent.children.push(c);
            } else {
                parent.children = [c];
            }
            // remove c from childList
            return null;
        }
        // keep top-level nodes
        return c;
    });
}

// Initialize Fancytree
$("#tree").fancytree({
    source: {url: "test-issue-431-googleapi.json"},
    postProcess: function(event, data){
        data.result = convertData(data.response);
    }
});

@mar10 mar10 added the question label May 9, 2015
@maxitromer
Copy link
Author

Man, this is much better than I was creating.

I put the code in the fiddle with an static example for the real life to make it works with AJAX.

http://jsfiddle.net/maxitromer/prncw2sL/6/

(I don't know why but I have to delete the header of the JSON to make it work.)

However ... works but with a little problem.

As you say "This sample also assumes that sub-tasks appear after their parents."

Google works with a "position" inside the JSON that controls the place in the tree and changes when you change the ITEM place.

And when you move the task the "position" changes but not the place in the JSON.

Thats why the sub-tasks could appear after or before their parents.

@mar10
Copy link
Owner

mar10 commented May 10, 2015

Then you simply could collect all node references before you traverse the hierarchy. Also sort all child lists as a last step:

function convertData(childList) {
    var parent,
        nodeMap = {};

    if( childList.kind === "tasks#tasks" ) {
        childList = childList.items;
    }
    // Pass 1: store all tasks in reference map
    $.each(childList, function(i, c){
        nodeMap[c.id] = c;
    });
    // Pass 2: adjust fields and fix child structure
    childList = $.map(childList, function(c){
        // Rename 'key' to 'id'
        c.key = c.id;
        delete c.id;
        // Set checkbox for completed tasks
        c.selected = (c.status === "completed");
        // Check if c is a child node
        if( c.parent ) {
            // add c to `children`array of parent node
            parent = nodeMap[c.parent];
            if( parent.children ) {
                parent.children.push(c);
            } else {
                parent.children = [c];
            }
            // remove c from childList
            return null;
        }
        // keep top-level nodes
        return c;
    });
    // Pass 3: sort chldren by 'position'
    $.each(childList, function(i, c){
        if( c.children && c.children.length > 1 ) {
            c.children.sort(function(a, b){
                return ((a.position < b.position) ? -1 : ((a.position > b.position) ? 1 : 0));
            });
        }
    });
    return childList;
}

// Initialize Fancytree
$("#tree").fancytree({
    checkbox: true,
    source: {url: "test-issue-431-googleapi.json"},
    postProcess: function(event, data){
        data.result = convertData(data.response);
    }
});

@mar10 mar10 closed this as completed May 10, 2015
@maxitromer
Copy link
Author

I put this new code in the fiddle and works like a charm.

I leave it here for future reference:

http://jsfiddle.net/prncw2sL/11/

Thank you Martin!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants