CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-jstree

jQuery tree plugin for creating interactive tree components with drag & drop, inline editing, checkboxes, search, and customizable node types

Pending
Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

SecuritybySnyk

Pending

The risk profile of this skill

Overview
Eval results
Files

contextmenu.mddocs/

Context Menu System

Customizable right-click context menus with support for custom items, submenus, and conditional visibility. The context menu plugin provides an intuitive way to access tree operations and custom actions through right-click interactions.

Capabilities

Context Menu Configuration

Configuration options for the context menu plugin behavior.

/**
 * Context menu plugin configuration
 */
interface ContextMenuConfig {
  /** Select node when showing context menu (default: true) */
  select_node?: boolean;
  /** Show menu at node position vs cursor position (default: true) */
  show_at_node?: boolean;
  /** Menu items configuration */
  items?: object|function;
}

interface ContextMenuItem {
  /** Display label */
  label?: string;
  /** Icon class */
  icon?: string;
  /** Action function */
  action?: function;
  /** Submenu items */
  submenu?: {[key: string]: ContextMenuItem};
  /** Separator before item */
  separator_before?: boolean;
  /** Separator after item */
  separator_after?: boolean;
  /** Conditional visibility */
  visible?: boolean|function;
  /** Conditional enablement */
  disabled?: boolean|function;
  /** Custom CSS class name */
  _class?: string;
  /** Shortcut key display */
  shortcut?: string;
  /** Shortcut key combination */
  shortcut_label?: string;
}

// Usage in tree initialization
const config = {
  "plugins": ["contextmenu"],
  "contextmenu": {
    "select_node": true,
    "show_at_node": true,
    "items": contextMenuBuilder
  }
};

Usage Examples:

// Initialize tree with context menu
$("#tree").jstree({
  "core": {
    "data": ["Item 1", "Item 2", "Folder"],
    "check_callback": true
  },
  "plugins": ["contextmenu"],
  "contextmenu": {
    "items": function(node) {
      return {
        "create": {
          "label": "Create",
          "action": function(data) {
            const inst = $.jstree.reference(data.reference);
            const obj = inst.get_node(data.reference);
            inst.create_node(obj, {}, "last", function(new_node) {
              setTimeout(function() { inst.edit(new_node); }, 0);
            });
          }
        }
      };
    }
  }
});

// Get instance for context menu operations
const tree = $("#tree").jstree(true);

Context Menu Methods

Methods for programmatically controlling context menus.

/**
 * Show context menu programmatically
 * @param obj - Node to show menu for
 * @param x - X coordinate (optional)
 * @param y - Y coordinate (optional)
 * @param e - Original event (optional)
 */
show_contextmenu(obj: string|object, x?: number, y?: number, e?: Event): void;

Usage Examples:

// Show context menu programmatically
tree.show_contextmenu("node_1");

// Show at specific coordinates
tree.show_contextmenu("node_1", 100, 200);

// Show context menu on custom trigger
$("#custom-button").click(function() {
  const selectedNodes = tree.get_selected();
  if (selectedNodes.length > 0) {
    tree.show_contextmenu(selectedNodes[0]);
  }
});

Static Menu Items

Configuration for static menu items that don't change based on context.

/**
 * Static menu items configuration
 */
interface StaticMenuItems {
  [key: string]: ContextMenuItem;
}

Usage Examples:

// Static menu items
$("#tree").jstree({
  "plugins": ["contextmenu"],
  "contextmenu": {
    "items": {
      "create": {
        "label": "Create",
        "icon": "fa fa-plus",
        "action": function(data) {
          const inst = $.jstree.reference(data.reference);
          const obj = inst.get_node(data.reference);
          inst.create_node(obj, {}, "last", function(new_node) {
            inst.edit(new_node);
          });
        }
      },
      "rename": {
        "label": "Rename",
        "icon": "fa fa-edit",
        "shortcut": "F2",
        "action": function(data) {
          const inst = $.jstree.reference(data.reference);
          const obj = inst.get_node(data.reference);
          inst.edit(obj);
        }
      },
      "delete": {
        "label": "Delete",
        "icon": "fa fa-trash",
        "shortcut": "Del",
        "separator_before": true,
        "action": function(data) {
          const inst = $.jstree.reference(data.reference);
          const obj = inst.get_node(data.reference);
          if (confirm("Delete " + obj.text + "?")) {
            inst.delete_node(obj);
          }
        }
      }
    }
  }
});

Dynamic Menu Items

Configuration for menu items that change based on the selected node or context.

/**
 * Dynamic menu items function
 * @param node - Node that was right-clicked
 * @returns Menu items object
 */
type DynamicMenuFunction = (node: object) => {[key: string]: ContextMenuItem};

Usage Examples:

// Dynamic menu based on node type
$("#tree").jstree({
  "plugins": ["contextmenu", "types"],
  "contextmenu": {
    "items": function(node) {
      const items = {};
      
      // Common items for all nodes
      items.rename = {
        "label": "Rename",
        "action": function(data) {
          const inst = $.jstree.reference(data.reference);
          inst.edit(data.reference);
        }
      };
      
      // Type-specific items
      if (node.type === "folder") {
        items.create_folder = {
          "label": "New Folder",
          "icon": "fa fa-folder",
          "action": function(data) {
            const inst = $.jstree.reference(data.reference);
            inst.create_node(data.reference, {
              "text": "New Folder",
              "type": "folder"
            }, "last", function(new_node) {
              inst.edit(new_node);
            });
          }
        };
        
        items.create_file = {
          "label": "New File",
          "icon": "fa fa-file",
          "action": function(data) {
            const inst = $.jstree.reference(data.reference);
            inst.create_node(data.reference, {
              "text": "New File",
              "type": "file"
            }, "last", function(new_node) {
              inst.edit(new_node);
            });
          }
        };
      }
      
      // Permission-based items
      if (hasDeletePermission(node)) {
        items.delete = {
          "label": "Delete",
          "icon": "fa fa-trash",
          "separator_before": true,
          "action": function(data) {
            if (confirm("Delete this item?")) {
              const inst = $.jstree.reference(data.reference);
              inst.delete_node(data.reference);
            }
          }
        };
      }
      
      return items;
    }
  }
});

Submenus

Configuration for nested submenu items.

/**
 * Submenu configuration
 */
interface SubmenuConfig {
  submenu: {[key: string]: ContextMenuItem};
}

Usage Examples:

// Context menu with submenus
$("#tree").jstree({
  "plugins": ["contextmenu"],
  "contextmenu": {
    "items": {
      "create": {
        "label": "Create",
        "icon": "fa fa-plus",
        "submenu": {
          "folder": {
            "label": "Folder",
            "icon": "fa fa-folder",
            "action": function(data) {
              const inst = $.jstree.reference(data.reference);
              inst.create_node(data.reference, {
                "text": "New Folder",
                "type": "folder"
              });
            }
          },
          "file": {
            "label": "File",
            "icon": "fa fa-file",
            "action": function(data) {
              const inst = $.jstree.reference(data.reference);
              inst.create_node(data.reference, {
                "text": "New File",
                "type": "file"
              });
            }
          },
          "separator": {
            "separator_before": true
          },
          "template": {
            "label": "From Template",
            "icon": "fa fa-copy",
            "submenu": {
              "html": {
                "label": "HTML File",
                "action": function(data) {
                  createFromTemplate(data.reference, "html");
                }
              },
              "css": {
                "label": "CSS File", 
                "action": function(data) {
                  createFromTemplate(data.reference, "css");
                }
              }
            }
          }
        }
      },
      "edit": {
        "label": "Edit",
        "submenu": {
          "rename": {
            "label": "Rename",
            "action": function(data) {
              const inst = $.jstree.reference(data.reference);
              inst.edit(data.reference);
            }
          },
          "properties": {
            "label": "Properties",
            "action": function(data) {
              showProperties(data.reference);
            }
          }
        }
      }
    }
  }
});

Conditional Menu Items

Configuration for menu items with conditional visibility and enablement.

/**
 * Conditional visibility function
 * @param key - Menu item key
 * @param opt - Menu options
 * @returns True if item should be visible
 */
type VisibilityFunction = (key: string, opt: object) => boolean;

/**
 * Conditional enablement function  
 * @param key - Menu item key
 * @param opt - Menu options
 * @returns True if item should be enabled
 */
type DisabledFunction = (key: string, opt: object) => boolean;

Usage Examples:

// Conditional menu items
$("#tree").jstree({
  "plugins": ["contextmenu"],
  "contextmenu": {
    "items": function(node) {
      return {
        "cut": {
          "label": "Cut",
          "action": function(data) {
            const inst = $.jstree.reference(data.reference);
            inst.cut(data.reference);
          },
          "visible": function(key, opt) {
            // Only show if node is not root
            return node.parent !== "#";
          }
        },
        "copy": {
          "label": "Copy",
          "action": function(data) {
            const inst = $.jstree.reference(data.reference);
            inst.copy(data.reference);
          }
        },
        "paste": {
          "label": "Paste",
          "action": function(data) {
            const inst = $.jstree.reference(data.reference);
            inst.paste(data.reference);
          },
          "visible": function(key, opt) {
            const inst = $.jstree.reference(opt.$trigger);
            return inst.can_paste();
          },
          "disabled": function(key, opt) {
            const inst = $.jstree.reference(opt.$trigger);
            return !inst.can_paste();
          }
        },
        "delete": {
          "label": "Delete",
          "action": function(data) {
            if (confirm("Delete this item?")) {
              const inst = $.jstree.reference(data.reference);
              inst.delete_node(data.reference);
            }
          },
          "visible": function(key, opt) {
            // Only show if user has delete permission
            return hasPermission("delete", node);
          }
        }
      };
    }
  }
});

Context Menu Events

Events triggered during context menu operations.

// Context menu specific events
"show_contextmenu.jstree": ContextMenuEvent;
"hide_contextmenu.jstree": ContextMenuEvent;

interface ContextMenuEvent {
  node: object;
  x: number;
  y: number;
  instance: jsTree;
}

Usage Examples:

// Listen for context menu events
$("#tree").on("show_contextmenu.jstree", function(e, data) {
  console.log("Context menu shown for:", data.node.text);
  console.log("Position:", data.x, data.y);
});

$("#tree").on("hide_contextmenu.jstree", function(e, data) {
  console.log("Context menu hidden");
});

// Custom context menu styling based on node
$("#tree").on("show_contextmenu.jstree", function(e, data) {
  const menuContainer = $(".jstree-contextmenu");
  
  // Add custom class based on node type
  menuContainer.removeClass("folder-menu file-menu");
  if (data.node.type === "folder") {
    menuContainer.addClass("folder-menu");
  } else if (data.node.type === "file") {
    menuContainer.addClass("file-menu");
  }
});

Advanced Context Menu Patterns

Advanced configuration patterns for complex scenarios.

/**
 * Advanced context menu patterns
 */
interface AdvancedContextMenuConfig {
  /** Multi-selection context menu */
  multi_selection?: boolean;
  /** Custom menu positioning */
  position?: function;
  /** Menu theme/styling */
  theme?: string;
  /** Animation settings */
  animation?: object;
}

Usage Examples:

// Multi-selection context menu
$("#tree").jstree({
  "plugins": ["contextmenu"],
  "contextmenu": {
    "items": function(node) {
      const inst = $.jstree.reference($("#tree"));
      const selected = inst.get_selected();
      const isMultiple = selected.length > 1;
      
      const items = {};
      
      if (isMultiple) {
        items.multi_delete = {
          "label": "Delete Selected (" + selected.length + ")",
          "icon": "fa fa-trash",
          "action": function(data) {
            if (confirm("Delete " + selected.length + " items?")) {
              inst.delete_node(selected);
            }
          }
        };
        
        items.multi_move = {
          "label": "Move Selected",
          "icon": "fa fa-arrows",
          "action": function(data) {
            // Show move dialog for multiple items
            showMoveDialog(selected);
          }
        };
      } else {
        // Single item context menu
        items.rename = {
          "label": "Rename",
          "action": function(data) {
            inst.edit(data.reference);
          }
        };
      }
      
      return items;
    }
  }
});

// Integration with other plugins
$("#tree").jstree({
  "plugins": ["contextmenu", "dnd", "clipboard"],
  "contextmenu": {
    "items": function(node) {
      const tree = $.jstree.reference($("#tree"));
      
      return {
        "cut": {
          "label": "Cut",
          "action": function(data) {
            tree.cut(data.reference);
          }
        },
        "copy": {
          "label": "Copy",
          "action": function(data) {
            tree.copy(data.reference);
          }
        },
        "paste": {
          "label": "Paste",
          "action": function(data) {
            tree.paste(data.reference);
          },
          "visible": function() {
            return tree.can_paste();
          }
        }
      };
    }
  }
});

Types

// Context menu data structures
interface ContextMenuData {
  reference: jQuery;
  element: jQuery;
  position: {x: number, y: number};
  node: object;
}

// Menu action function signature
type MenuActionFunction = (data: ContextMenuData) => void;

// Context menu settings
interface ContextMenuSettings {
  select_node: boolean;
  show_at_node: boolean;
  items: object|DynamicMenuFunction;
}

docs

checkbox.md

configuration.md

contextmenu.md

core.md

dnd.md

events.md

index.md

plugins.md

search.md

tile.json