Pull to refresh

How to по деревьям на jQuery

Reading time 5 min
Views 7.1K
Часто встречаются задачи, в которых требуется отобразить древовидную структуру взаимосвязей каких-либо сущностей. Например, навигация по файловой системе, меню сайта или содержание учебника.
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:

Демо работы с деревьями можно посмотреть тут.
Tags:
Hubs:
+32
Comments 12
Comments Comments 12

Articles