- PVSM.RU - https://www.pvsm.ru -

Custom Tree v2 jQuery plugin + draggable

На днях решил вернуться к перепиливанию одного своего старенького Open Source проекта.
В процессе обдумывания решил, что предыдущий компонент с деревом [1] в его нынешнем виде меня больше не устраивает.

Хотелось чего-нибудь более Event Driven, с понятным и простым API.

Сейчас решил, что оно уже готово для Public.

Берите, пользуйтесь [2].
Или посмотрите на example в рамках GH-pages [3].

Под катом краткий перевод краткой документации по 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

Источник [4]


Сайт-источник PVSM.RU: https://www.pvsm.ru

Путь до страницы источника: https://www.pvsm.ru/plugins/40067

Ссылки в тексте:

[1] компонент с деревом: http://habrahabr.ru/post/142603/

[2] Берите, пользуйтесь: https://github.com/wentout/CustomTree2

[3] example в рамках GH-pages: http://wentout.github.io/CustomTree2/

[4] Источник: http://habrahabr.ru/post/188778/