Dnd, как ограничить доступ к определенным типам node?
У меня 37 различных типов node.
Я пытаюсь реализовать перетаскивание.
Это работает, но мне нужно ограничить то, какие типы можно перетаскивать и где их можно отбросить.
К сожалению, я не могу найти полезную информацию в документах (http://www.jstree.com/documentation).
До сих пор я пробовал три метода:
сначала: определение возвращаемых значений true или false в обратном вызове drag_check в зависимости от типа node:
$("#demo1").jstree({
"dnd" : {
"drag_check" : function () {
second: привязка к событию prepare_move.jstree и возврат истинных или ложных значений в зависимости от типа node:
.bind("prepare_move.jstree", function (e, data) {
if (data.rslt.o.attr("typ") === "tpop") {
третий: использование плагинов типов и определение допустимых дочерних элементов:
$("#tree").jstree( {
"types": {
"type_attr": "typ",
"valid_children": ["ap_ordner_pop", "ap_ordner_apziel", "ap_ordner_erfkrit", "ap_ordner_apber", "ap_ordner_ber", "ap_ordner_beob", "iballg", "ap_ordner_ibb", "ap_ordner_ibartenassoz"],
"types": {
"ap_ordner_pop": {
"valid_children": "pop"
},
"pop": {
"valid_children": ["pop_ordner_tpop", "pop_ordner_popber", "pop_ordner_massnber"],
"new_node": "neue Population"
},
"pop_ordner_tpop": {
"valid_children": "tpop"
}
Но я все равно могу удалить большинство узлов почти где угодно.
Как это должно быть сделано?
Или вы можете указать мне на хороший пример?
Помощь очень ценится.
Ответы
Ответ 1
На цель вам нужно будет проверить, разрешено ли вам отбрасывать туда объект. Кажется, у вас есть какой-то механизм для запаха объекта, как вы указали:
if (data.rslt.o.attr("typ") === "tpop")
Это хорошо. Используйте этот метод, чтобы различать один тип объекта от другого при выполнении многопоточной операции. В приведенном ниже примере я использую имена классов из источника и цели, чтобы выполнить свой собственный уникальный "тест запаха". Не копируйте и не вставляйте, иначе вы будете запутаны. Вам нужно использовать свой собственный тест, чтобы принять/отклонить перетаскивание из одного дерева в другое. Все мои тесты выполняются в функции crrm check_move.
.jstree({
"crrm" : {
input_width_limit : 200,
move : {
always_copy : "multitree", // false, true or "multitree"
open_onmove : false,
default_position: "last",
check_move : function (m) {
if(!m.np.hasClass("someClassInTarget")) return false;
if(!m.o.hasClass("someClassInSource")) return false;
return true;
}
}
},
"dnd" : {
copy_modifier : $.noop,
drop_target : ".someWrapperClassInSource",
drop_check : function (data) { return true; },
drop_finish : function (data) {
$.jstree._reference(this.get_container()).remove($(data.o));
},
drag_target : ".someClassInSource",
drag_finish : function (data) {;},
drag_check : function (data) { return { after : false, before : false, inside : true }; }
},
Ответ 2
Для тех, кто ищет ответы, используя jstree v3. Плагин crrm удален, и вместо этого вы захотите использовать check_callback.
В моем случае все, что я хотел сделать, это прекратить перетаскивание дочерних элементов в другие дочерние элементы. Там может быть лучший способ сделать это, но после нескольких часов небольшого прогресса это то, что сработало для меня.
Я считаю, что вам также нужно установить для параметра "check_while_dragging" dnd значение true, чтобы вызвать "check_callback" при перетаскивании.
Здесь моя инициализация jsTree:
$("#jsTree").jstree({
'core': {
'data': window.treeData,
'themes': {
'icons': false
},
'check_callback': function(operation, node, node_parent, node_position, more) {
// operation can be 'create_node', 'rename_node', 'delete_node', 'move_node' or 'copy_node'
// in case of 'rename_node' node_position is filled with the new node name
if (operation === "move_node") {
return node_parent.original.type === "Parent"; //only allow dropping inside nodes of type 'Parent'
}
return true; //allow all other operations
}
},
"state": { "key": "<%=Request.QueryString["type"]%>_infotree" },
"dnd": {
check_while_dragging: true
},
"plugins": ["state", "dnd", "types"]
})