3

I was wondering if anyone could help me out with jQuery file tree (jQuery File Tree)

I was wondering if/how it would be possible to set some kind of variable that will tell the file tree to have a certain folder open on load. (eg. folder /images/fruit/ to be open by default)

Here's the code to call the filetree:

$('#container_id').fileTree({ 
  root: '/images/' 
}, function(file) {
  alert(file);
});

And here's the filetree.js file:

// jQuery File Tree Plugin
//
// Version 1.01
//
// Cory S.N. LaViska
// A Beautiful Site (http://abeautifulsite.net/)
// 24 March 2008
//
// Visit http://abeautifulsite.net/notebook.php?article=58 for more information
//
// Usage: $('.fileTreeDemo').fileTree( options, callback )
//
// Options:  root           - root folder to display; default = /
//           script         - location of the serverside AJAX file to use; default = jqueryFileTree.php
//           folderEvent    - event to trigger expand/collapse; default = click
//           expandSpeed    - default = 500 (ms); use -1 for no animation
//           collapseSpeed  - default = 500 (ms); use -1 for no animation
//           expandEasing   - easing function to use on expand (optional)
//           collapseEasing - easing function to use on collapse (optional)
//           multiFolder    - whether or not to limit the browser to one subfolder at a time
//           loadMessage    - Message to display while initial tree loads (can be HTML)
//
// History:
//
// 1.01 - updated to work with foreign characters in directory/file names (12 april 2008)
// 1.00 - released (24 March 2008)
//
// TERMS OF USE
// 
// This plugin is dual-licensed under the GNU General Public License and the MIT License and
// is copyright 2008 a Beautiful Site, LLC. 
//
if(jQuery) (function($){

    $.extend($.fn, {
        fileTree: function(o, h) {
            // Defaults
            if( !o ) var o = {};
            if( o.root == undefined ) o.root = '/';
            if( o.script == undefined ) o.script = 'jqueryFileTree.php';
            if( o.folderEvent == undefined ) o.folderEvent = 'click';
            if( o.expandSpeed == undefined ) o.expandSpeed= 500;
            if( o.collapseSpeed == undefined ) o.collapseSpeed= 500;
            if( o.expandEasing == undefined ) o.expandEasing = null;
            if( o.collapseEasing == undefined ) o.collapseEasing = null;
            if( o.multiFolder == undefined ) o.multiFolder = true;
            if( o.loadMessage == undefined ) o.loadMessage = 'Loading...';

            $(this).each( function() {

                function showTree(c, t) {
                    $(c).addClass('wait');
                    $(".jqueryFileTree.start").remove();
                    $.post(o.script, { dir: t }, function(data) {
                        $(c).find('.start').html('');
                        $(c).removeClass('wait').append(data);
                        if( o.root == t ) $(c).find('ul:hidden').show(); else $(c).find('ul:hidden').slideDown({ duration: o.expandSpeed, easing: o.expandEasing });
                        bindTree(c);
                    });
                }
                function bindTree(t) {
                    $(t).find('li a').bind(o.folderEvent, function() {
                        if( $(this).parent().hasClass('directory') ) {
                            if( $(this).parent().hasClass('collapsed') ) {
                                // Expand
                                if( !o.multiFolder ) {
                                    $(this).parent().parent().find('ul').slideUp({ duration: o.collapseSpeed, easing: o.collapseEasing });
                                    $(this).parent().parent().find('li.directory').removeClass('expanded').addClass('collapsed');
                                }
                                $(this).parent().find('ul').remove(); // cleanup
                                showTree( $(this).parent(), escape($(this).attr('rel').match( /.*\// )) );
                                $(this).parent().removeClass('collapsed').addClass('expanded');
                            } else {
                                // Collapse
                                $(this).parent().find('ul').slideUp({ duration: o.collapseSpeed, easing: o.collapseEasing });
                                $(this).parent().removeClass('expanded').addClass('collapsed');
                            }
                        } else {
                            h($(this).attr('rel'), $(this).attr('name'), $(this).attr('title'), $(this).attr('id'));
                        }
                        return false;
                    });
                    // Prevent a from triggering the # on non-click events
                    if( o.folderEvent.toLowerCase != 'click' ) $(t).find('li a').bind('click', function() { return false; });
                }
                // Loading message
                $(this).html('<ul class="jqueryFileTree start"><li class="wait">' + o.loadMessage + '<li></ul>');
                // Get the initial file list
                showTree( $(this), escape(o.root) );
            });
        }
    });

})(jQuery);

Every time I've tried to mess around with it, I keep killing it, as my javascript isn't that great. Any help would be appreciated! :)

SoulieBaby
  • 5,405
  • 25
  • 95
  • 145

5 Answers5

11

Add an extra default property to jqueryFileTree.js for folders to expand:

if (o.expandedFolders == undefined) o.expandedFolders = [];

Update the code to call the filetree to include the default folders to expand:

$(document).ready(function () {
        $('#container_id').fileTree({ 
             root: '/', 
             expandedFolders: ['/images/','/images/fruit/'] 
            }, function (file) {
            alert(file);
        });
    });

Then add the following jquery code directly after the bindTree(c); line to the showTree(c, t) function in jqueryFileTree.js:

if (o.expandedFolders != null) {
    $(c).find(".directory.collapsed").each(function (i,f) {
       if ($.inArray($(f).children().attr('rel'), $(o.expandedFolders)) != -1) {
           showTree($(f), escape($(f).children().attr('rel').match(/.*\//)));
           $(f).removeClass('collapsed').addClass('expanded');
       }
    });
}
Bermo
  • 4,921
  • 1
  • 28
  • 31
4

There's an easier way to expand predefined folder without having to use array of folders.

I've modified Bermo's awesome hack so you don't have to write each parent folder (folders below the one you want to see opened) in array, instead it uses regular expression to find parent folders automatically:

jqueryFileTree.js

Line 47, after if( o.loadMessage == undefined ) o.loadMessage = 'Loading...';:

if(o.expanded == undefined) o.expanded = '';

Line 58, after bindTree(c);:

if (o.expanded != null) {
    $(c).find('.directory.collapsed').each(function (i, f) {
        if ((o.expanded).match($(f).children().attr('rel'))) {
            showTree($(f), escape($(f).children().attr('rel').match(/.*\//)));
            $(f).removeClass('collapsed').addClass('expanded');
        };
    });
}

yourpage.htm

$(document).ready(function () {
    $('#container_id').fileTree({ 
         root: '/', 
         expanded: '/images/fruit/'
        }, function (file) {
        alert(file);
    });
});
Matija
  • 316
  • 3
  • 6
  • Good solution, but in order to make this work the path must begin and end with a slash. – Michiel Jan 24 '14 at 12:30
  • for me worked in this way: $('#container_id').fileTree({ root: '/', script: 'php/myScript.php' , expanded: '/images/fruit/' }, function(file) {.... – Jam Nov 27 '18 at 12:35
1

Here's another improvement to Bermo and Matija's code:

Add this after the default properties:

var expansion_completed = false;

Then replace the if block after bindTree() with this:

if (o.expanded != false) {
    $(c).find(".directory.collapsed").each(function (idx, li) {
        var rel = $(li).children().attr('rel');
        if (!expansion_completed && o.expanded.substr(0, rel.length) == rel) {
            showTree(li, rel);
            $(li).removeClass('collapsed').addClass('expanded');
        }
        if (o.expanded == rel) {
            expansion_completed = true;
            $(li).children("a").css('background-color', '#6080e0').css('color', 'white').css('font-weight', 'bold');
        }
    });
}

There are a few advantages:

  1. First, it doesn't use regular expressions, so it should be faster and less error-prone.
  2. It remembers when it has completed the expansion, and will not re-expand everything if you close a parent and then re-expand it.
  3. It highlights the currently selected folder.
Gromer
  • 9,861
  • 4
  • 34
  • 55
Steve M
  • 11
  • 1
1

So this is totally a hack but it should work for what you want. I tried to give a solution where it didn't modify the tree source code. So what I would do for now is:

var pathToNode = "root/folder";
$("A[rel=pathToNode]").click();

This will simulate a click on the folder. The only problem is that if the folder is several layers deep then you will need to either attach an event to the click so that you know they are clicking and then wait so many seconds after depending on the normal load times. You can bind a secondary event to the click method like this:

$("A[rel=pathToNode]").click(function(){ alert("my test"); });

So now if you click that item in the tree you should see an alert as well as have it expand.

spinon
  • 10,760
  • 5
  • 41
  • 59
0

Just trigger click event on it .

Kai
  • 2,967
  • 1
  • 22
  • 28