1 сентября 2011 в 09:54

How to по деревьям на jQuery из песочницы

Часто встречаются задачи, в которых требуется отобразить древовидную структуру взаимосвязей каких-либо сущностей. Например, навигация по файловой системе, меню сайта или содержание учебника.
image
Самым простым вариантом отобразить древовидную структуру в HTML являются списки. Но нас интересуют деревья, обладающие динамическими свойствами. Без javascript тут не обойтись. Так как решение нужно обычно быстро, то использование jQuery позволяет создавать динамические деревья, экономя прилично времени на кодинге. Чтобы сэкономить себе еще кучу времени идем на поисковик и ищем подходящее решение. В целом часто на этом дело создание дерева на сайте и ограничивается, но бывают ситуации, когда дерево подходит, но не имеет какой-то маленькой фишки и тут уже ни чего не остается, кроме как модифицировать имеющиеся дерево.


Сегодня на столе для препарирования у нас два дерева: Treeview и jQuery File Tree.

Для Treeview требуется сделать корректное добавление новых узлов в дерево. С одной стороны может показаться, что задача странная, т.к. у дерева есть возможность добавлять новые узлы через селектор add. Вот так:

var tree = $(".selector").treeview();
$(".button").click(function() {
 var newSublist = $("<li><span class='folder'>New Sublist</span><ul>" +
   "<li><span class='file'>Item1</span></li>" +
   "<li><span class='file'>Item2</span></li></ul></li>").appendTo(tree);
 tree.treeview({
  add: newSublist
 });
});


Но у данного подхода есть недостаток, узел можно добавить либо в конец дерева, либо только в строго определенный подузел. А вот что бы новый узел добавлялся в выбранный подузел сделать видимо не просто, потому как поиск положительных результатов, отличных от описанных в документации, не дал.

Поэтому применим метод внешнего вмешательства в поведение дерева:

$(function() {
  var pervios_node; //запоминаем предыдущй выбранный узел
  $("#browser").treeview({
    toggle: function() {//когда дерево раскрыввается или сворачивается
      $(this).addClass("selector"); //добавляем свой класс
    //проверяем есть ли предыдущий узел и не равен ли он текущему (пару раз кликнули)
      if (pervios_node!=undefined && pervios_node!=this) {
                            //удаляем свой класс из предыдущего узла
        $(pervios_node).removeClass("selector");
      };
      pervios_node=this;
    }
  });
  $("#add").click(function() {
    //добавление узла в выбранный текущий узел
    var branches = $("<li><span class='folder'>New Sublist</span><ul><li><span class='file'>Item2</span></li></ul></li>").appendTo("li.selector ul:first");
    $("#browser").treeview({
      add: branches
    });
  });
});


Ключевым моментом вмешательства является appendTo(«li.selector ul:first»). Мы добавили класс selector, чтобы пометить текущий выбранный узел и теперь можем его найти и добавить новые узлы.

Второе дерево предназначено для отображения структуры файловой системы. Но у него есть один небольшой недостаток. Если отключить в коннекторе отображение файлов, оставить только каталоги, то нельзя просмотреть содержимое коневой папки.

Для решения данной проблемы требуется изменить само дерево, за одно исправить небольшую ошибку, которая присутствует в оригинальном скрипте.

Приступим. Перейдем к скрипту дерева jqueryFileTree.js и после задания значений по умолчанию для опций дерева добавим стрку:

var show_root=1; //true

Ниже в функции итератора исправим передачу параметров в POST запросе, добавив недостающий параметр root (теперь коннектор не будет ругаться на недостающую переменную), в текущем варианте данный параметр делаем пустой строкой, т.к. он учувствует в формировании путей в коннкторе. И наконец, добавляем параметр регулирующий добавление корневого узла в дерево — showroot.

$.post(o.script, { dir: t, root: '',showroot:show_root }, function(data) {

});
show_root=0; //false


После функции обнуляем параметр добавления корневого узла в дерево, чтобы он не появлялся в подузлах.
Последним штрихом будет изменение коннектора.

$_POST['dir'] = urldecode($_POST['dir']);
$root= urldecode($_POST['root']);
$show_root=(bool)urldecode($_POST['showroot']);

if( file_exists($root . $_POST['dir']) ) {
  $files = scandir($root . $_POST['dir']);
  natcasesort($files);
  if( count($files) > 2 ) { /* The 2 accounts for . and .. */
    echo "<ul class=\"jqueryFileTree\" style=\"display: none;\">";
    //показываем корневую дирректорию
    if($show_root)
    {
      echo "<li class=\"directory collapsed\"><a href=\"#\" rel=\"" . htmlentities($_POST['dir'] . ".") . "/\">root</a></li>";      
    }
    else
    {
      // All dirs
      foreach( $files as $file ) {
        if( file_exists($root . $_POST['dir'] . $file) &&
                $file != '.' &&
                $file != '..' &&
                is_dir($root . $_POST['dir'] . $file) ) {
          echo "<li class=\"directory collapsed\"><a href=\"#\" rel=\"" . htmlentities($_POST['dir'] . $file) . "/\">" . htmlentities($file) . "</a></li>";
        }
      }      
      // All files    
    }
    echo "</ul>";  
  }
}



Таким образом, у нас появляется корневая директория, от которой уже остальные видны как подузлы дерева.

UPD:

Демо работы с деревьями можно посмотреть тут.
Максим Михеев @Ceiceron
карма
12,0
рейтинг 0,0
Похожие публикации
Самое читаемое Разработка

Комментарии (12)

  • +11
    Когда искал хорошее дерево с множеством методов для одного проекта остановился на jstree.com/
    • 0
      Да, это отличный экземпляр, разглядывал его. Но т.к. для моих задач нужно было что-то попроще, но с маленькой фичей, то jsTree отложил. С другой стороны мне понравилась реализация jQuery File Tree, сделано просто, легко модифицировать, предсказуемо работает, мало весит.
    • 0
      Да, jsTree 0.9 очень даже не плох, а вот jsTree 1 мне не понравился вовсе + дока уменьшилась
  • +2
    dynatree еще один интересный экземпляр. чтото среднее между предложенным вам и монструозным jstree
    • +1
      Отличный экземпляр. По крайней мере на первый взгляд очень понравился.
  • +5
    Не хватает скринов и Live Demo… ИМХО
    • 0
      Сделалдемо. Была проблема с хостингом и временем, поэтому задержался с его публикацией.
  • –1
    Сервис лично переписки у меня что-то сегодня не работает (может какой очередной бан?) Не возьмётесь за фриланс-задачу по javascript — поправить скрипт для самого последнего IE. Поправить без наворотов для конкретного браузера — просто разобраться, как пользоваться стандартными библиотеками от Google в IE.

  • 0
    Недавно тоже долго изучал деревья. Остановился на jsTree так как нужна была работа с json.
  • +1
    [grammar_nazi]
    pervios – WTF?!
    [/grammar_nazi]
    • –1
      Я так сократил.
      • +1
        тогда уж previous)

Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.