Das contextmenu
Plugin unterstützt dies bereits. Aus der Dokumentation, die Sie verlinkt haben:
items
: Erwartet ein Objekt oder eine Funktion, die ein Objekt zurückgeben soll . Wenn eine Funktion verwendet wird, wird sie im Kontext des Baums ausgelöst und erhält ein Argument - den Knoten, auf den mit der rechten Maustaste geklickt wurde.
Anstatt contextmenu
ein fest codiertes Objekt zum Arbeiten anzugeben, können Sie die folgende Funktion bereitstellen. Es überprüft das Element, auf das geklickt wurde, auf eine Klasse mit dem Namen "Ordner" und entfernt das Menüelement "Löschen", indem es aus dem Objekt gelöscht wird:
function customMenu(node) {
// The default set of all items
var items = {
renameItem: { // The "rename" menu item
label: "Rename",
action: function () {...}
},
deleteItem: { // The "delete" menu item
label: "Delete",
action: function () {...}
}
};
if ($(node).hasClass("folder")) {
// Delete the "delete" menu item
delete items.deleteItem;
}
return items;
}
Beachten Sie, dass oben die Löschoption vollständig ausgeblendet wird. Mit dem Plugin können Sie jedoch auch ein Element anzeigen, während Sie dessen Verhalten deaktivieren, indem Sie _disabled: true
es dem entsprechenden Element hinzufügen . In diesem Fall können Sie stattdessen items.deleteItem._disabled = true
innerhalb der if
Anweisung verwenden.
Sollte offensichtlich sein, aber denken Sie daran, das Plugin mit der customMenu
Funktion zu initialisieren, anstatt mit dem, was Sie zuvor hatten:
$("#tree").jstree({plugins: ["contextmenu"], contextmenu: {items: customMenu}});
// ^
// ___________________________________________________________________|
Bearbeiten: Wenn Sie nicht möchten, dass das Menü bei jedem Rechtsklick neu erstellt wird, können Sie die Logik in den Aktionshandler für das Menüelement Löschen selbst einfügen.
"label": "Delete",
"action": function (obj) {
if ($(this._get_node(obj)).hasClass("folder") return; // cancel action
}
Erneut bearbeiten: Nach dem Betrachten des jsTree-Quellcodes sieht es so aus, als würde das Kontextmenü jedes Mal neu erstellt, wenn es trotzdem angezeigt wird (siehe show()
und parse()
Funktionen), sodass ich bei meiner ersten Lösung kein Problem sehe.
Ich mag jedoch die von Ihnen vorgeschlagene Notation mit einer Funktion als Wert für _disabled
. Ein möglicher Weg, den Sie erkunden sollten, besteht darin, ihre parse()
Funktion mit Ihrer eigenen zu versehen, die die Funktion bei bewertet disabled: function () {...}
und das Ergebnis darin speichert _disabled
, bevor Sie das Original aufrufen parse()
.
Es wird auch nicht schwierig sein, den Quellcode direkt zu ändern. Zeile 2867 der Version 1.0-rc1 ist die relevante:
str += "<li class='" + (val._class || "") + (val._disabled ? " jstree-contextmenu-disabled " : "") + "'><ins ";
Sie können einfach eine Zeile vor dieser hinzufügen, die dies überprüft $.isFunction(val._disabled)
, und wenn ja val._disabled = val._disabled()
. Dann sende es den Machern als Patch :)
var items
sich außerhalb der Funktion zu bewegen , damit sie nur einmal erstellt wird, und eine Auswahl von Elementen aus der Funktion zurückzugeben, z. B.return {renameItem: items.renameItem};
oderreturn {renameItem: items.renameItem, deleteItem: items.deleteItem};
<a>
Element, auf das geklickt wurde, unter gespeichert ist$.vakata.context.tgt
. Also versuchen Sie nachzuschauen$.vakata.context.tgt.attr("rel")
.if ($(node).hasClass("folder"))
hat nicht funktioniert. aber das tat:if (node.children.length > 0) { items.deleteItem._disabled = true; }
Implementiert mit verschiedenen Knotentypen:
Und die customMenu-Funktion:
Funktioniert wunderbar.
quelle
type
eher auf das Attribut als auf eine mit jQuery erhaltene CSS-Klasse stützt .'action': function () { /* action */ }
in das zweite Snippet ein? Was ist, wenn Sie die "normalen" Funktionen und Menüelemente verwenden möchten, aber einfach eines davon entfernen möchten (z. B. Löschen entfernen, aber Umbenennen und Erstellen beibehalten)? Meiner Meinung nach hat das OP sowieso wirklich darum gebeten. Sicherlich müssen Sie die Funktionen für Dinge wie Umbenennen und Erstellen nicht neu schreiben, wenn Sie ein anderes Element wie Löschen entfernen.items
Liste der Objekte und geben dannnode.type
am Ende dercustomMenu
Funktion an , welche dieser Elemente für ein bestimmtes Element entfernt werden sollen. Wenn der Benutzer auf einen bestimmten Knoten klickttype
, werden im Kontextmenü alle Elemente abzüglich aller in der Bedingung am Ende dercustomMenu
Funktion entfernten Elemente aufgelistet . Sie schreiben keine Funktionen neu (es sei denn, jstree hat sich seit dieser Antwort vor drei Jahren geändert. In diesem Fall ist sie möglicherweise nicht mehr relevant).Alles klären.
An Stelle von:
Benutze das:
quelle
Ich habe die vorgeschlagene Lösung für die Arbeit mit Typen etwas anders angepasst, vielleicht kann sie jemand anderem helfen:
Wobei # {$ id_arr [$ k]} der Verweis auf den div-Container ist ... in meinem Fall verwende ich viele Bäume, sodass der gesamte Code an den Browser ausgegeben wird, aber Sie haben die Idee. Grundsätzlich möchte ich alles die Kontextmenüoptionen, aber nur 'Erstellen' und 'Einfügen' auf dem Laufwerksknoten. Offensichtlich mit den richtigen Bindungen zu diesen Operationen später:
quelle
Übrigens: Wenn Sie nur Optionen aus dem vorhandenen Kontextmenü entfernen möchten, hat dies bei mir funktioniert:
quelle
Sie können den @ Box9-Code so ändern, dass er Ihren Anforderungen an die dynamische Deaktivierung des Kontextmenüs entspricht:
Sie müssen ein Attribut "xyz" in Ihre XML- oder JSOn-Daten einfügen
quelle
Ab jsTree 3.0.9 musste ich so etwas verwenden
weil das
node
bereitgestellte Objekt kein jQuery-Objekt ist.quelle
Davids Antwort scheint gut und effizient zu sein. Ich habe eine andere Variante der Lösung gefunden, bei der Sie das Attribut a_attr verwenden können, um verschiedene Knoten zu unterscheiden, und basierend darauf können Sie verschiedene Kontextmenüs generieren.
Im folgenden Beispiel habe ich zwei Arten von Knoten verwendet: Ordner und Dateien. Ich habe auch verschiedene Symbole mit Glyphicon verwendet. Für Dateitypknoten können Sie nur das Kontextmenü zum Umbenennen und Entfernen aufrufen. Für Ordner stehen alle Optionen zur Verfügung: Datei erstellen, Ordner erstellen, umbenennen, entfernen.
Für ein vollständiges Code-Snippet können Sie https://everyething.com/Example-of-jsTree-with-different-context-menu-for-different-node-type anzeigen
Die anfänglichen JSON-Daten waren wie folgt, wobei der Knotentyp in a_attr erwähnt wird.
Verwenden Sie als Teil des Kontextmenüelements zum Erstellen einer Datei und eines Ordners den folgenden Code als Dateiaktion.
als Ordneraktion:
quelle