Plugin contextmenu
đã có hỗ trợ cho việc này. Từ các tài liệu liên quan đến bạn:
items
: hy vọng một đối tượng hoặc một chức năng, mà phải trả lại một đối tượng. Nếu một hàm được sử dụng nó được kích hoạt trong bối cảnh của cây và nhận được một đối số - nút đã được nhấp chuột phải.
Vì vậy, thay vì cung cấp cho contextmenu
một đối tượng được mã hóa cứng để hoạt động, bạn có thể cung cấp chức năng sau. Nó kiểm tra các yếu tố đó được nhấp cho một lớp có tên là "thư mục", và loại bỏ các "xóa" mục trình đơn bằng cách xóa nó từ đối tượng:
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;
}
Lưu ý rằng ở trên sẽ ẩn tùy chọn xóa hoàn toàn, nhưng plugin cũng cho phép bạn hiển thị một mục trong khi tắt hành vi của nó, bằng cách thêm _disabled: true
vào mục có liên quan. Trong trường hợp này, bạn có thể sử dụng items.deleteItem._disabled = true
trong câu lệnh if
để thay thế.
nên được rõ ràng, nhưng hãy nhớ để khởi plugin với customMenu
chức năng thay vì những gì bạn đã từng:
$("#tree").jstree({plugins: ["contextmenu"], contextmenu: {items: customMenu}});
// ^
// ___________________________________________________________________|
Edit: Nếu bạn không muốn menu để được tái tạo trên mỗi nhấp chuột phải, bạn có thể đặt logic trong trình xử lý hành động để tự xóa mục menu.
"label": "Delete",
"action": function (obj) {
if ($(this._get_node(obj)).hasClass("folder") return; // cancel action
}
Chỉnh sửa lần nữa: Sau khi xem xét mã nguồn jsTree, nó trông giống như ContextMenu đang được tái tạo mỗi khi nó được hiển thị anyway (xem các chức năng show()
và parse()
), vì vậy tôi không thấy vấn đề với giải pháp đầu tiên của tôi.
Tuy nhiên, tôi thực hiện như ký hiệu bạn đang đề xuất, với hàm làm giá trị cho _disabled
.Một con đường tiềm năng để khám phá là quấn hàm parse()
của bạn với hàm của riêng bạn để đánh giá hàm tại disabled: function() {...}
và lưu trữ kết quả trong _disabled
, trước khi gọi số parse()
gốc.
Sẽ không khó để sửa đổi mã nguồn trực tiếp. Dòng 2867 của phiên bản 1.0-rc1 là phù hợp nhất:
str += "<li class='" + (val._class || "") + (val._disabled ? " jstree-contextmenu-disabled " : "") + "'><ins ";
Bạn chỉ có thể thêm một dòng trước này để kiểm tra $.isFunction(val._disabled)
, và nếu như vậy, val._disabled = val._disabled()
. Sau đó gửi cho người tạo dưới dạng bản vá :)
Cảm ơn. Tôi nghĩ rằng tôi đã từng thấy một giải pháp liên quan đến việc thay đổi chỉ những gì cần thay đổi từ mặc định (thay vì tạo lại toàn bộ menu từ đầu). Tôi sẽ chấp nhận câu trả lời này nếu không có giải pháp nào tốt hơn trước khi tiền thưởng hết hạn. – MGOwen
@MGOwen, khái niệm I * am * sửa đổi "mặc định", nhưng có đúng là đối tượng được tạo lại mỗi khi hàm được gọi. Tuy nhiên, mặc định cần được nhân bản trước, nếu không bản thân mặc định sẽ được sửa đổi (và bạn sẽ cần logic phức tạp hơn để hoàn nguyên nó về trạng thái ban đầu). Một thay thế tôi có thể nghĩ là di chuyển 'var items' sang bên ngoài của hàm để nó chỉ được tạo một lần và trả về một số mục từ hàm, ví dụ: 'return {renameItem: items.renameItem};' hoặc 'return {renameItem: items.renameItem, deleteItem: items.deleteItem};' –
Tôi thích cái cuối cùng đặc biệt, nơi bạn sửa đổi nguồn jstree. Tôi đã thử nó và nó hoạt động, chức năng được gán cho "_disabled" (trong ví dụ của tôi) chạy.Nhưng, nó không giúp được gì bởi vì tôi không thể truy cập vào nút (ít nhất tôi cũng cần thuộc tính rel để lọc các nút theo kiểu nút) từ bên trong phạm vi của hàm. Tôi đã thử kiểm tra các biến tôi có thể vượt qua từ mã nguồn jstree nhưng không thể tìm thấy nút. Bất kỳ ý tưởng? – MGOwen