#javascript #fancytree
Вопрос:
Я знаю, что в этом примере я объединяю множество расширений, и это может быть моей проблемой, но мне интересно, как конкретно взаимодействуют в fancytree dnd5, multi и edit. Я обнаружил, что при первоначальной загрузке своей страницы я могу без проблем перетаскивать несколько узлов (с помощью сдвига или управления). Однако, если я изменю имя узла, я потеряю возможность перетаскивать несколько узлов. Только отдельные узлы будут dnd. Есть ли способ сохранить многоузловой dnd после редактирования?
<script>
$("#treegrid").fancytree({
source: {
url: 'mysource.php',
cache: false
},
activate: function(event, data) {
},
aria: true,
debugLevel: 4,
extensions: ["dnd5", "edit", "filter","multi","table","ariagrid"],
dnd5: {
preventVoidMoves: true, // Prevent moving nodes 'before self', etc.
preventRecursion: true, // Prevent dropping nodes on own descendants
preventSameParent: false, // Prevent dropping nodes under the same direct parent
autoExpandMS: 1000,
multiSource: true, // drag all selected nodes (plus current node)
// focusOnClick: true,
// refreshPositions: true,
dragStart: function(node, data) {
// allow dragging `node`:
data.effectAllowed = "all";
data.dropEffect = data.dropEffectSuggested; //"link";
// data.dropEffect = "move";
return true;
},
dragEnter: function(node, data) {
data.node.info("dragEnter", data);
// prevent dragging to a node (only allow dragging into folder)
if(node.isFolder() amp;amp; !data.otherNode.isFolder()){
return true;
} else
return 'before';
},
dragOver: function(node, data) {
data.dropEffect = data.dropEffectSuggested; //"link";
return true;
},
dragEnd: function(node, data) {
data.node.info("dragEnd", data);
},
dragDrop: function(node, data) {
// This function MUST be defined to enable dropping of items on the tree.
var sourceNodes = data.otherNodeList,
copyMode = data.dropEffect !== "move";
if( data.hitMode === "after" ){
// If node are inserted directly after tagrget node one-by-one,
// this would reverse them. So we compensate:
sourceNodes.reverse();
}
$.each(sourceNodes, function(i, o){
if (o.folder !== true) // only move files, not folders
{
o.info("move to " node ": " data.hitMode);
o.moveTo(node, data.hitMode);
/* code removed - process and save */
}
});
node.debug("drop", data);
node.setExpanded();
if (node.isFolder() amp;amp; (node.getLevel() !== 1))
node.sortChildren();
else if (node.parent.folder)
node.parent.sortChildren();
else // must be dragging to the root level
{
var rootNode = $.ui.fancytree.getTree("#treegrid").getRootNode();
rootNode.sortChildren();
}
}
},
edit: {
triggerStart: ["dblclick", "f2", "mac enter"],
adjustWidthOfs: 100,
inputCss: { minWidth: "5em" },
beforeEdit: function(event, data){
// Return false to prevent edit mode
},
edit: function(event, data){
// Editor was opened (available as data.input)
},
beforeClose: function(event, data){
// Return false to prevent cancel/save (data.input is available)
console.log(event.type, event, data);
if( data.originalEvent.type === "mousedown" ) {
// We could prevent the mouse click from generating a blur event
// (which would then again close the editor) and return `false` to keep
// the editor open:
// data.originalEvent.preventDefault();
// return false;
// Or go on with closing the editor, but discard any changes:
// data.save = false;
}
},
save: function(event, data){
// Save data.input.val() or return false to keep editor open
console.log("save...", this, data);
// code removed send ajax update
return true;
},
close: function(event, data){
// Editor was removed
if( data.save ) {
// Since we started an async request, mark the node as preliminary
//$(data.node.span).addClass("pending");
}
data.node.setSelected(false); // de-selects current node after saving, this was persisting for some reason
data.node.parent.sortChildren(cmp, true);
}
},
filter: {
autoApply: true, // Re-apply last filter if lazy data is loaded
autoExpand: true, // Expand all branches that contain matches while filtered
counter: true, // Show a badge with number of matching child nodes near parent icons
fuzzy: false, // Match single characters in order, e.g. 'fb' will match 'FooBar'
hideExpandedCounter: true, // Hide counter badge if parent is expanded
hideExpanders: false, // Hide expanders if all child nodes are hidden by filter
highlight: true, // Highlight matches by wrapping inside <mark> tags
leavesOnly: false, // Match end nodes only
nodata: true, // Display a 'no data' status node if result is empty
mode: "hide" // "dimm" Grayout unmatched nodes (pass "hide" to remove unmatched node instead)
},
table: {
checkboxColumnIdx: 3, // render the checkboxes into the 4th column
nodeColumnIdx: 0 // render the node title into the 1st column
},
ariagrid: {
cellFocus: $( "#optionsForm [name=cellFocus]" ).find( ":selected" ).val(),
label: "Fancytree ARIA sample"
},
defaultGridAction: function( event, data ) {
// Called when ENTER is pressed in cell-mode.
// Return false to prevent default
data.node.debug(event.type, data);
if( !data.activeTd ) {
alert( "Custom default action for row: " data.node.title );
// we don't return false, so default action is applied:
} else if ( data.colIdx === 4 ) {
// eslint-disable-next-line no-alert
alert( "Custom default action: " data.node.title );
return false;
}
},
/* This code makes links in the file tree work */
click: function(event, data){
var node = data.node,
orgEvent = data.originalEvent;
var targetType = data.targetType;
if(node.data.href amp;amp; targetType == 'icon'){
window.open(node.data.href, (orgEvent.ctrlKey || orgEvent.metaKey) ? "_blank" /*node.data.target*/ : node.data.target);
}
},
icon: function(event, data) {
if( data.node.isFolder() ) { return "custom-1"; }
},
renderColumns: function( event, data ) {
//code removed
}
});```