На днях решил вернуться к перепиливанию одного своего старенького Open Source проекта.
В процессе обдумывания решил, что предыдущий компонент с деревом в его нынешнем виде меня больше не устраивает.
Хотелось чего-нибудь более Event Driven, с понятным и простым API.
Сейчас решил, что оно уже готово для Public.
Берите, пользуйтесь.
Или посмотрите на example в рамках GH-pages.
Под катом краткий перевод краткой документации по API.
UPD: в комментариях мой код для организации перетаскивания.
Исполнено оно в виде jQuery плагина.
Пример конфига, т.е. того, что передаётся когда вы «создаёте» дерево:
$('#tree_content').customTree({
root : 'top',
init : {
callback : function (controller, tree) {
info('Init callback.');
}
},
// for leaf callbacks
handlers : {
added : function (leaf, controller, tree) {
},
loaded : function (leaf, controller, tree) {
},
parsed : function (leaf, controller, tree) {
},
open : function (leaf, controller, tree) {
},
close : function (leaf, controller, tree) {
},
hover : function (leaf, controller, tree) {
},
unhover : function (leaf, controller, tree) {
},
focus : function (leaf, controller, tree) {
},
beforeblur : function (callback, leaf, controller, tree) {
},
blur : function (leaf, controller, tree) {
},
deleted : function (leaf, controller, tree) {
},
dblclick : function (leaf, controller, tree) {
}
},
listeners : {
// click, dblclick, contextmenu up the element Label
contextmenu : function (leaf, controller, tree, event) {
},
dblclick : function (leaf, controller, tree, event) {
}
},
storeLoaded : false,
focusParentOnClose : true,
// focusByDblClick: true,
// blurFromContainerClick : false,
// blurFromContainerDblClick : false,
labelsBreak : {
by : 50,
expandOnHover : false,
expandOnSelect : true
},
loader : function (path, callback) {
// ... your code for nodes loading
}
});
В рамках кода используется строгое соглашение по параметрам ноды, приходящей на ParsingRendering, поэтому привожу пример единичной ноды (leaf):
{
// – должно быть уникальным в рамках текущего узла,
'unique_naming_string' : {
// – опционально, используется для представления,
text : 'string',
// – опционально, указывает на то, является ли данный leaf папкой,
folder : [true || false],
// – опционально, указывает на то, нужно ли "открыть" папку
open : [true || false]
// любые другие свойства могут быть дополнительно переданы, вы сможете их использвать
}
}
Объяснения {
- root – имя для root пути узла
- init – опции начальной загрузки
// то, что будет использовано для загрузки root
init : {
// отсрочка в миллисекундах или null
delay : null,
// имя класса установленное на root во время первоначальной загрузки
// если не будет установлено, то preloader не будет индицирован
preloader : 'preloader',
// function (controller, tree) будет вызван после загрузки
callback : null,
// jQuery метод, который будет использован для "показа" root
method : 'fadeIn',
// если true (default), то загрузка произойдёт сразу после delay
auto : true,
// путь узла, который нужно focus после загрузки
focus : null
}
handlers ( leaf, controller, tree ) – предустановленные обработчики событий.
Все принимают текущий узел, контроллер и объект дерева.
Но beforeblur принимает ещё и callback как первый параметр.
Если Вам, допустим, нужно проверять, можно ли blur текущий узел.
Если «да», тогда этот callback нужно вызвать.
Иначе просто не вызывайте его, тогда blur не произойдёт.
Если blur должен был быть произведён, потому, что нужно было сделать focus для другого узла, то если не вызвать этот callback, ни blur текущего ни focus нужного произведён не будет.
Естественно, эти манипуляции с callback для beforeblur будут возможны только если вы вообще передадите в конфиг handler.beforeblur.
loader ( path, callback ) – то, к чему контроллер будет обращаться для загрузки leaf.
Принимает ['tree.root', 'leaf.name'] в качестве path.
Должен вернуть JS Object!
listeners – стандартыне jQuery .on( callbacks для текстового элемента узла.
Т.е., если, допустим, нужно contextmenu или кастомный click, то нужно использовать listeners.
theme – CSS PREFIX_ для классов при рендере
cls – набор CSS классов при рендере:
cls : {
// для root
root : 'tree_root',
// для места, где плюс и минус
control : 'tree_control',
// для места, где текущий статус, например "загружается"
status : 'tree_leaf_status',
// для текстового поля
text : 'tree_leaf_text',
// для "папок"
folder : 'folder',
// для выделенного по focus()
selected : 'selected',
// когда мышка над текстом
hover : 'hover',
// когда загружается текущий узел
loader : 'loader',
// когда папка открыта
open : 'open',
// для всего контейнера
container : 'container',
// когда не нужно позволять выделение текста
supressLabelTextSelection : 'unselectable',
supressTreeTextSelection : 'unselectable'
}
html – HTML тэги для рендера:
html : {
// root container
tree : '<UL>',
// leaf container
leaf : '<LI>',
// то, где будут children узла
children : '<UL>',
// где хранится текст и контролы +- status
heading : '<DIV>',
// то где +-
control : '<SPAN>',
// то, где статус
status : '<SPAN>',
// то, где текст
text : '<SPAN>',
// сам контейнер
container : '<DIV>'
}
control – строки, использованные для +-:
control : {
close : '+',
open : '–'
},
storeLoaded: true || false – сохранять «свёрнутые» узлы, или перезагружать каждый раз
focusParentOnClose: true || false – выделить родительский элемент, если его потомок имел focus
focusByDblClick: true || false – выделять по двойному щелчку
blurFromContainerClick: true || false – blur когда щелкают root
blurFromContainerDblClick: true || false – blur когда дважды щелкают root
labelsBreak: – текстовые caption узла могут быть длинными, опции для «обрезки» если нужны:
labelsBreak : {
// на какое количество символов делать перенос строк
by : 0,
// чем переносить
str : 'n',
// всегда полностью отображать все строки
expandAlways : false,
// отображать все, когда hover
expandOnHover : false,
// отображать все, когда focused
expandOnSelect : true
}
Controller API
- getPath ( leaf ) – возвращает URL ARRAY для Leaf Object: [ 'top', 'leaf_name', 'child_name'… ]
- refresh ( leaf, callback, andOpen ) – перезагружает переданный 'leaf',
'callback' используется по завершении,
pass 'andOpen' если нужно развернуть свёрнутый узел - blur ( leaf ) – делаем blur узлу
- focus ( leaf ) – делаем focus узлу
- x – текущий конфиг
- x.current – текущий выделенный узел
- init – если config.init.auto == false, здесь будет функция вызова init дерева
Надеюсь, что кому-нибудь это всё пригодится.
Автор: wentout