fancytree

how to not activate fancytree node when clicking the expander


The goal is to have a fancytree, with urls in the nodes, which you can follow by clicking on the link but also on the folder and page icons. Clicking on the page and folder icons works via the activate event. For description of the setup see below (added the other options because these might influence it as well).

But what now also happens, is that activate responds on a click on the expander. Is there a way to recognize in activate if the expander is clicked and ignore that case?

Or alternative, the click function might interesting, but I do not know how I can use it as it seems a quite general event. (Below is similar as example here) It suggests that I can handle activate there. But I do not see how I can recognize activate on a click event, such that I prevent it only if coming from the expander.

Adding if(data.targetType === 'expander') { return false } to the click event blocks too much, for example, also the unfolding/folding of nodes.

$tree.fancytree({
    extensions: [],
    clickFolderMode: 3, // expand with single click instead of dblclick
    autoActivate: false, // we use scheduleAction(). Otherwise, looping in combination with clicking
    activeVisible: false,
    focus: function(event, data) {
        // Auto-activate focused node after 1 second (practical for use with keyboard)
        if(data.node.key){
            data.node.scheduleAction("activate", 1000);
        }
    },
    blur: function(event, data) {
        data.node.scheduleAction("cancel");
    },
    // click: function(event, data) { //just for logging info(testing)
    //     logEvent(event, data, ", targetType=" + data.targetType);
    //     // return false to prevent default behavior (i.e. activation, ...)
    //     //return false;
    // },
    activate: function(event, data){
        const node = data.node;

        //prevent looping (hns is false or a page id)
        if(node.key === JSINFO.id || node.data.hns === JSINFO.id) {
            //node is equal to current page
            return;
        }

        if(node.data.url === false) {
            return false;
        }

        if(node.data.url){
            window.location.href = node.data.url;
            // console.log("reload");
        }
    },
    init: function(event, data) {
        data.tree.reactivate();
    },
    enhanceTitle: function(event, data) {
        let node = data.node;

        if(node.data.url === false) {
            return;
        }
        data.$title.html("<a href='" + node.data.url + "'>" + node.title + "</a>");
    },
    source: {
        url: DOKU_BASE + 'lib/exe/ajax.php',
        data: {
            ...
        }
    },
    lazyLoad: function(event, data) {
        const node = data.node;
        // Issue an Ajax request to load child nodes
        data.result = {
            url: DOKU_BASE + 'lib/exe/ajax.php',
            data: {
                ..
            }
        }
    }
});

Solution

  • You could try something like this:

    $("#tree").fancytree({
      [...]
      click: function(event, data) {
        var node = data.node,
            // 'title' | 'prefix' | 'expander' | 'checkbox' | 'icon'
            targetType = data.targetType;
    
        if(targetType === 'expander') {
          node.toggleExpanded(); //restore default behaviour
          return false; // prevent default action
        }
    
      },
    });
    

    See https://stackoverflow.com/a/58569782/19166