@progress/kendo-ui
Version:
This package is part of the [Kendo UI for jQuery](http://www.telerik.com/kendo-ui) suite.
1,586 lines (1,580 loc) • 75.8 kB
JavaScript
//#region ../src/filemanager/commands.js
(function($, undefined) {
var kendo = window.kendo, extend = $.extend, deferred = $.Deferred, Class = kendo.Class;
var Command = Class.extend({ init: function(options) {
this.options = options;
this.filemanager = options.filemanager;
} });
var CreateFolderCommand = Command.extend({
init: function(options) {
Command.fn.init.call(this, options);
},
_renameNewFolder: function(uid) {
let that = this, fileManager = that.filemanager || that, widgetComponent = fileManager.view().widgetComponent, uidAttribute = kendo.attr("uid"), folderElement = widgetComponent.items().filter(function(idx, element) {
return $(element).attr(uidAttribute) == uid;
}).first();
if (folderElement.length > 0) {
widgetComponent.select(folderElement[0]);
fileManager.executeCommand({
command: "RenameCommand",
options: {
target: $(folderElement),
item: fileManager.getSelected()[0]
}
});
}
},
exec: function() {
var that = this, filemanager = that.filemanager, commandStack = filemanager._commandStack, dataSource = filemanager._viewDataSource || filemanager.dataSource, removeProxy = that._remove.bind(that);
that._item = dataSource._createNewModel();
that._item._fromCreateFolderCommand = true;
let sanitizedItem = that._item.toJSON();
let command = {
item: sanitizedItem,
renameFolderProxy: that._renameNewFolder
};
commandStack.push(command).fail(removeProxy);
dataSource.add(that._item);
},
_remove: function() {
var that = this, filemanager = that.filemanager, dataSource = filemanager._viewDataSource || filemanager.dataSource;
dataSource.pushDestroy(that._item);
}
});
var RenameCommand = Command.extend({
init: function(options) {
Command.fn.init.call(this, options);
},
exec: function() {
var that = this, target = that.options.target, filemanager = that.filemanager, commandStack = filemanager._commandStack, viewItem = filemanager._view.widgetComponent.dataItem(target);
if (target && viewItem) {
commandStack.push({
target,
item: viewItem
});
that.filemanager._view.edit(target);
} else {
that._renameTreeViewItem(target);
}
},
_renameTreeViewItem: function(target) {
var that = this, filemanager = that.filemanager, commandStack = filemanager._commandStack, uid = target.data("uid"), item = that.filemanager.treeView.widgetComponent.dataSource.getByUid(uid), realItem = that.filemanager.dataSource.get(item.id);
that.filemanager._prompt({
type: "rename",
defaultInput: realItem.name,
target
}).done(function(newName) {
commandStack.push({
target,
item: realItem
});
realItem.set("name", newName);
});
}
});
var DeleteCommand = Command.extend({
init: function(options) {
Command.fn.init.call(this, options);
},
exec: function() {
var that = this, target = that.options.target, filemanager = that.filemanager, items = filemanager.getSelected(), viewItem = that.filemanager._view.widgetComponent.dataItem(target), itemsToRemove;
if (target && target.is(".k-selected") && items && items.length) {
itemsToRemove = items;
} else if (target && viewItem) {
itemsToRemove = viewItem;
} else if (target) {
var uid = target.data("uid");
var item = that.filemanager.treeView.widgetComponent.dataSource.getByUid(uid);
var realItem = that.filemanager.dataSource.get(item.id);
itemsToRemove = realItem;
}
filemanager._confirm({
type: "delete",
target
}).done(function() {
that.removeItems(itemsToRemove);
});
},
removeItems: function(items) {
var that = this;
that._itemsToRemove = Array.isArray(items) ? items : [items];
that._removeItem();
},
_removeItem: function() {
var that = this, filemanager = that.filemanager, commandStack = filemanager._commandStack, dataSource = filemanager.dataSource, itemToRemove = !!that._itemsToRemove.length && that._itemsToRemove.splice(0, 1)[0];
if (itemToRemove) {
commandStack.push({ item: itemToRemove }).then(that._removeItem.bind(that), that._removeItem.bind(that));
dataSource.remove(itemToRemove);
}
}
});
var CopyCommand = Command.extend({
init: function(options) {
Command.fn.init.call(this, options);
},
exec: function() {
var that = this, filemanager = that.filemanager, dataSource = filemanager.dataSource, commandStack = filemanager._commandStack, items = that.options.items, target = dataSource.get(that.options.target), targetDataSource = target.children;
for (var i = 0; i < items.length; i++) {
var item = dataSource.get(items[i]).toJSON();
item.fileManagerNewItem = true;
commandStack.push({
item,
target
});
targetDataSource.add(item);
}
}
});
var MoveCommand = Command.extend({
init: function(options) {
var that = this;
Command.fn.init.call(that, options);
that._itemsToRemove = [];
},
exec: function() {
var that = this, filemanager = that.filemanager, commandStack = filemanager._commandStack, dataSource = filemanager.dataSource, items = that.options.items, target = dataSource.get(that.options.target), targetDataSource = target.children, promises = [];
for (var i = 0; i < items.length; i++) {
var item = dataSource.get(items[i]);
var cloning = item.toJSON();
cloning.fileManagerNewItem = true;
var promise = commandStack.push({
item,
target
}).then(that._delete.bind(that));
promises.push(promise);
targetDataSource.add(cloning);
}
kendo.whenAll(promises).always(that._removeItem.bind(that));
},
_delete: function(data) {
var that = this;
that._itemsToRemove.push(data.item);
},
_removeItem: function() {
var that = this, filemanager = that.filemanager, commandStack = filemanager._commandStack, dataSource = filemanager.dataSource, itemToRemove = !!that._itemsToRemove.length && that._itemsToRemove.splice(0, 1)[0];
if (itemToRemove) {
commandStack.push({ item: itemToRemove }).then(that._removeItem.bind(that), that._removeItem.bind(that));
dataSource.remove(itemToRemove);
}
}
});
var SortCommand = Command.extend({
init: function(options) {
Command.fn.init.call(this, options);
},
exec: function() {
var that = this, options = that.options, filemanager = that.filemanager, sortOptions = filemanager.defaultSortOption;
extend(sortOptions, {
dir: options.dir,
field: options.field
});
filemanager._view.widgetComponent.dataSource.sort([filemanager.folderSortOption, sortOptions]);
}
});
var SearchCommand = Command.extend({
init: function(options) {
Command.fn.init.call(this, options);
},
exec: function() {
var that = this, options = that.options, filemanager = that.filemanager, filter = {
field: options.field,
operator: options.operator,
value: options.value || ""
};
filemanager._view.widgetComponent.dataSource.filter(filter);
}
});
var ChangeViewCommand = Command.extend({
init: function(options) {
Command.fn.init.call(this, options);
},
exec: function() {
var that = this, options = that.options, filemanager = that.filemanager;
filemanager.view(options.value);
filemanager.resize(true);
}
});
var OpenDialogCommand = Command.extend({
init: function(options) {
Command.fn.init.call(this, options);
},
exec: function() {
var that = this, filemanager = that.filemanager, dialog = filemanager[that.options.type];
if (dialog) {
dialog.open();
} else {
window.console.warn(kendo.format("The {0} dialog is not available!", that.options.type));
}
}
});
var TogglePaneCommand = Command.extend({
init: function(options) {
Command.fn.init.call(this, options);
},
exec: function() {
var that = this, filemanager = that.filemanager, pane = filemanager[that.options.type], resizable = that.getResizable();
if (pane) {
pane.toggle();
if (resizable) {
filemanager.wrapper.find(resizable.options.handle).toggle();
}
}
},
getResizable: function() {
var that = this, filemanager = that.filemanager, type = that.options.type;
if (!filemanager._resizeDraggable) {
return;
}
return filemanager._resizeDraggable[type];
}
});
var CommandStack = Class.extend({
init: function() {
var that = this;
that._stack = {};
that._keys = [];
},
push: function(data) {
var that = this, guid = kendo.guid();
that._keys.push(guid);
that._stack[guid] = {
guid,
data,
deferred: deferred()
};
return that._stack[guid].deferred;
},
next: function() {
var that = this, key = that.keys().splice(0, 1), nextCommand = that._stack[key];
return nextCommand;
},
resolve: function(command) {
var that = this;
delete that._stack[command.guid];
command.deferred.resolve(command.data);
},
reject: function(command) {
var that = this;
delete that._stack[command.guid];
command.deferred.reject(command.data);
},
keys: function() {
return this._keys;
},
empty: function() {
return this.keys().length === 0;
}
});
extend(kendo.ui, { filemanager: {
FileManagerCommand: Command,
CommandStack,
commands: {
CreateFolderCommand,
RenameCommand,
DeleteCommand,
MoveCommand,
CopyCommand,
SortCommand,
SearchCommand,
ChangeViewCommand,
OpenDialogCommand,
TogglePaneCommand
}
} });
})(window.kendo.jQuery);
//#endregion
//#region ../src/filemanager/view.js
(function($, undefined) {
var kendo = window.kendo, ui = kendo.ui, Observable = kendo.Observable, extend = $.extend, encode = kendo.htmlEncode, keys = kendo.keys, NAVIGATE = "navigate", SELECT = "select", EXPAND = "expand", CHANGE = "change", OPEN = "open", LOAD = "load", KEYDOWN = "keydown", KEYDOWNACTION = "keydownAction", NS = ".kendoFileManagerViewComponent", fileManagerDraggables = [], fileManagerDragOrigin = null;
var registerViewComponent = function(componentName, component) {
ui.filemanager.ViewComponents[componentName] = component;
};
var getViewComponent = function(componentName) {
return ui.filemanager.ViewComponents[componentName] || null;
};
var Component = Observable.extend({
init: function(widget, element, options) {
var that = this;
that.element = element;
that.options = options;
if (widget) {
that.widgetComponent = new widget(element, options);
} else {
throw new Error("The widget for the ViewComponent is not available! Please add the corresponding scripts!");
}
Observable.fn.init.call(that);
},
_bindEvents: function() {
this.widgetComponent.bind("dataBinding", this._binding.bind(this));
this.widgetComponent.bind("dataBound", this._bound.bind(this));
},
_binding: function(ev) {
if (this.trigger("dataBinding", ev)) {
ev.preventDefault();
}
},
_bound: function() {
this.trigger("dataBound");
},
_setDSOptions: function(options, dataSourceOptions) {
if (!options.dataSource && dataSourceOptions) {
options.dataSource = dataSourceOptions;
}
},
_initDragAndDrop: function(element, filter) {
var that = this;
filter = filter || that.options.dropFilter;
element = element || that.element;
that.draggable = element.kendoDraggable({
filter,
hint: that._hint.bind(that),
cursorOffset: {
top: -10,
left: -50
},
holdToDrag: true,
ignore: "input, .k-focusable",
hold: that._hold.bind(that)
}).data("kendoDraggable");
that.draggable.userEvents.minHold = 150;
that.droptarget = element.kendoDropTargetArea({
filter,
drop: that._onDrop.bind(that),
dragenter: function(ev) {
ev.dropTarget.addClass("k-filemanager-drop-target");
},
dragleave: function(ev) {
ev.dropTarget.removeClass("k-filemanager-drop-target");
}
}).data("kendoDraggable");
},
_hold: function(ev) {
var that = this, target = ev.currentTarget;
if (!target.is(".k-selected")) {
if (that.widgetComponent.selectable) {
that.widgetComponent.selectable.clear();
}
that.widgetComponent.select(target);
}
if (that.widgetComponent.selectable) {
that.widgetComponent.selectable.userEvents.cancel();
}
},
_hint: function(target) {
var that = this, item = that.widgetComponent.dataItem(target), selectedItems = that.widgetComponent.select();
fileManagerDragOrigin = that.widgetComponent;
fileManagerDraggables = selectedItems;
if (selectedItems.length > 1) {
return `<div class='k-filemanager-drag-hint'>${kendo.ui.icon("file")} <span>${selectedItems.length} ${that.options.messages.items}</span></div>`;
}
return `<div class='k-filemanager-drag-hint'>${kendo.ui.icon(item.isDirectory ? "folder" : "file")} <span>${item.name}</span></div>`;
},
_onDrop: function(ev) {
var that = this, target = that.widgetComponent.dataItem(ev.dropTarget), targetId = target.id, itemIds = [];
if (!target.isDirectory) {
return;
}
for (var i = 0; i < fileManagerDraggables.length; i++) {
var id = fileManagerDragOrigin.dataItem(fileManagerDraggables[i]).id;
itemIds.push(id);
}
this.trigger("drop", {
target: targetId,
items: itemIds
});
},
getSelected: function() {
throw new Error("Not Implemented!");
},
refresh: function(dataSource) {
this.widgetComponent.setDataSource(dataSource);
},
destroy: function() {
kendo.destroy(this.element);
}
});
extend(kendo.ui.filemanager, {
ViewComponent: Component,
ViewComponents: {},
registerViewComponent,
getViewComponent
});
var ListView = Component.extend({
init: function(element, options, explicitOptions) {
var that = this, dataSourceOptions = explicitOptions.dataSource, messages = explicitOptions.messages;
options = extend({}, that.defaultOptions, options, {
messages,
ariaLabel: explicitOptions.ariaLabel
});
that._setDSOptions(options, dataSourceOptions);
options.kendoKeydown = options.kendoKeydown || that._kendoKeydown.bind(that);
Component.fn.init.call(this, ui.ListView, element, options);
that.listView = that.widgetComponent;
that._bindEvents();
if (explicitOptions.draggable !== false && !dataSourceOptions.isLocalBinding) {
that._initDragAndDrop();
}
},
defaultOptions: {
layout: "flex",
flex: {
direction: "row",
wrap: "wrap"
},
selectable: kendo.support.mobileOS ? "row" : "multiple",
template: ({ name, extension, isDirectory }) => `<div class='k-listview-item' title='${encode(name)}${encode(extension ?? "")}'>` + `<div class='k-file-preview'>${kendo.ui.icon({
icon: !isDirectory ? kendo.getFileGroup(extension, true) : "folder",
iconClass: "k-file-icon",
size: "xxxlarge"
})}</div>` + `<div class='k-file-name file-name'>${encode(name)}${encode(extension ?? "")}</div>` + "</div>",
editTemplate: ({ extension, isDirectory }) => "<div class='k-listview-item'>" + `<div class='k-file-preview'>${kendo.ui.icon({
icon: !isDirectory ? kendo.getFileGroup(extension, true) : "folder",
iconClass: "k-file-icon",
size: "xxxlarge"
})}</div>` + "<div class='k-file-name'><span class='k-textbox k-input'><input type='text' class='k-input-inner' data-bind='value:name' name='name' required='required' /><span></div>" + "</div>",
dropFilter: ".k-listview-item",
navigatable: true
},
_bindEvents: function() {
var that = this, listView = that.listView;
listView.bind(CHANGE, that._select.bind(that));
listView.element.on("dblclick" + NS, that._dblClick.bind(that));
listView.element.on("mousedown" + NS, ".k-listview-item:not(.k-edit-item)", that._mousedown.bind(that));
listView.element.on(KEYDOWN + NS, ".k-edit-item", that._keydown.bind(that));
listView.element.on(KEYDOWN + NS, that._keydownAction.bind(that));
listView.bind("edit", function(ev) {
var sender = ev.sender;
var input = ev.item.find("input");
input.on("blur", function() {
var isDirty = sender._modelFromElement(sender.editable.element)?.dirty;
sender._closeEditable();
if (!isDirty) {
that.trigger("cancel");
}
});
});
listView.bind("cancel", function() {
that.trigger("cancel");
});
Component.fn._bindEvents.call(this);
},
_select: function() {
var that = this, dataItems = that.getSelected();
that.trigger(SELECT, { entries: dataItems });
},
_keydown: function(ev) {
var that = this;
if (ev.keyCode === kendo.keys.ESC) {
that.listView._closeEditable();
that.trigger("cancel");
}
},
_keydownAction: function(ev) {
var that = this, target = $(ev.target).find(".k-focus");
if (target.length && !target.is(".k-edit-item")) {
that.trigger(KEYDOWNACTION, {
target,
keyCode: ev.keyCode
});
}
},
_mousedown: function(ev) {
var that = this, node = $(ev.target).closest(".k-listview-item");
if (ev.which === 3 && !node.is(".k-selected")) {
that.listView.selectable.clear();
that.listView.select(node);
}
},
_kendoKeydown: function(ev) {
var that = this;
if (ev.keyCode === keys.ENTER && !ev.preventKendoKeydown) {
that._handleEnterKey(ev);
}
},
_handleEnterKey: function(ev) {
var that = this, target = $(ev.target), node = that.listView.current();
if (that.widgetComponent.editable && target.is("input")) {
target.trigger("blur");
} else if (!that.widgetComponent.editable) {
that._triggerOpen(node);
}
ev.preventKendoKeydown = true;
},
_dblClick: function(ev) {
var that = this, node = $(ev.target).closest(".k-listview-item");
that._triggerOpen(node);
},
_triggerOpen: function(node) {
var that = this;
if (node.is(".k-edit-item")) {
return;
}
var item = that.listView.dataItem(node);
if (item) {
that.trigger(OPEN, { entry: item });
}
},
addFolder: function() {
this.listView.add();
},
edit: function(target) {
var that = this, selected = that.listView.select();
that.listView.edit(target || selected);
},
getSelected: function() {
var that = this, items = that.listView.select(), dataItems = [];
for (var i = 0; i < items.length; i++) {
var item = that.listView.dataItem(items[i]);
if (item) {
dataItems.push(item);
}
}
return dataItems;
},
destroy: function() {
this.listView.element.off(NS);
Component.fn.destroy.call(this);
}
});
ui.filemanager.registerViewComponent("list", ListView);
var TreeView = Component.extend({
init: function(element, options, explicitOptions) {
var that = this, messages = explicitOptions.messages;
options = extend({}, that.defaultOptions, options, { messages });
Component.fn.init.call(this, ui.TreeView, element, options);
that.treeView = that.widgetComponent;
that._bindEvents();
if (explicitOptions.draggable !== false && !explicitOptions.isLocalBinding) {
that._initDragAndDrop();
}
},
defaultOptions: {
dataTextField: "name",
dropFilter: ".k-treeview-item"
},
_refreshDataSource: function(ev) {
var that = this, treeView = that.treeView, action = ev.action, node = ev.node, parentNode = null, treeEl = treeView.element, activeDescendant = treeEl.attr("aria-activedescendant"), items = ev.items.filter(function(item) {
return item.isDirectory;
}).map(function(item) {
return extend({}, item.toJSON(), {
id: item.id || kendo.guid(),
hasChildren: item.hasDirectories && item.hasChildren,
items: []
});
});
if (node) {
const uid = treeView.dataSource.get(node.id)?.uid;
parentNode = uid ? treeView.findByUid(uid) : null;
if (parentNode && items.length) {
treeView._progress(parentNode, false);
}
}
if (!items.length) {
return;
}
if (parentNode && (action == "itemloaded" || action === "sync")) {
parentNode.find(".k-treeview-item").each(function(index, item) {
treeView.remove(item);
});
treeView.append(items, parentNode);
if (that._shouldFocus) {
treeView.current(parentNode);
treeView.focus();
}
} else if (action == "remove") {
this._remove(items[0].id);
} else if (action == "itemchange") {
var existingItem = treeView.dataSource.get(items[0].id);
if (existingItem) {
existingItem.set(ev.field, items[0][ev.field]);
} else if (parentNode) {
treeView.append(items[0], parentNode);
}
} else if (!treeView.dataSource.data().length) {
treeView.append(items);
} else if (action === "sync" || action === undefined && !parentNode) {
treeView.items().each(function(index, item) {
treeView.remove(item);
});
treeView.append(items);
if (that._shouldFocus) {
treeView.current(treeView._nextVisible($()));
treeView.focus();
}
}
if (!!activeDescendant && treeEl.find("#" + activeDescendant).length === 0) {
treeEl.removeAttr("aria-activedescendant");
}
},
_remove: function(id) {
var that = this, treeView = that.treeView, dataSource = treeView.dataSource, item = dataSource.get(id), node;
if (item) {
node = treeView.findByUid(item.uid);
treeView.remove(node);
}
},
_bindEvents: function() {
var that = this;
that.treeView.bind(SELECT, that._navigate.bind(that));
that.treeView.bind(EXPAND, that._expand.bind(that));
that.treeView.element.on(KEYDOWN, that._keydownAction.bind(that));
},
_keydownAction: function(ev) {
var that = this, target = $(ev.target).find(".k-focus").closest(".k-treeview-item");
that.trigger(KEYDOWNACTION, {
target,
keyCode: ev.keyCode
});
},
_expand: function(ev) {
var that = this, treeView = that.treeView, entry = treeView.dataItem(ev.node);
ev.preventDefault();
that.trigger(LOAD, { entryId: entry.id });
},
_navigate: function(ev) {
var that = this, node = ev.node, entry = that.treeView.dataItem(node), path = entry.id;
ev.preventDefault();
that.trigger(NAVIGATE, {
path,
entry: entry.toJSON()
});
},
_hold: $.noop,
getSelected: function() {
var that = this, selectedItem = that.treeView.element.find(".k-selected").closest(".k-treeview-item"), item = that.treeView.dataItem(selectedItem);
return item;
},
refresh: function(id) {
var that = this, treeView = that.treeView, entry = treeView.dataSource.get(id), node = entry && treeView.findByUid(entry.uid);
if (entry && node) {
treeView.element.find(".k-selected").removeClass("k-selected");
node.find("> span.k-treeview-item-content").removeClass("k-hover").addClass("k-selected");
}
},
reload: function() {
this.treeView.dataSource.read();
}
});
ui.filemanager.registerViewComponent("tree", TreeView);
if (kendo.ui.Grid) {
var Grid = Component.extend({
init: function(element, options, explicitOptions) {
var that = this, dataSourceOptions = explicitOptions.dataSource, messages = explicitOptions.messages;
options = extend({}, that.defaultOptions, options, { messages });
that._setDSOptions(options, dataSourceOptions);
that._setupColumns(options, messages);
options.kendoKeydown = options.kendoKeydown || that._kendoKeydown.bind(that);
Component.fn.init.call(this, ui.Grid, element, options);
that.grid = that.widgetComponent;
that._bindEvents();
if (explicitOptions.draggable !== false && !dataSourceOptions.isLocalBinding) {
that._initDragAndDrop();
}
if (explicitOptions.ariaLabel) {
that.element.find("[role=grid]").attr("aria-label", explicitOptions.ariaLabel);
}
},
defaultOptions: {
selectable: kendo.support.mobileOS ? "row" : "multiple",
editable: {
mode: "inline",
confirmation: false
},
sortable: true,
dropFilter: "tr:not(.k-grid-edit-row)",
navigatable: true
},
_setupColumns: function(options, messages) {
if (!options.columns) {
options.columns = [
{
field: "name",
title: messages.nameField || "Name",
template: function(item) {
let icon = !item.isDirectory ? kendo.getFileGroup(item.extension, true) : "folder";
let entryName = kendo.htmlEncode(item.name + (item.extension ?? ""));
let template = "<div class='file-group-icon'>" + kendo.ui.icon(icon) + "</div>" + "<div class='file-name'>" + entryName + "<div>";
return template;
}
},
{
field: "created",
title: messages.dateCreatedField,
format: "{0:G}"
},
{
field: "size",
title: messages.sizeField,
template: function(item) {
if (item.size > 0) {
return kendo.getFileSizeMessage(item.size);
} else {
return "";
}
}
}
];
}
},
_bindEvents: function() {
var that = this, grid = that.grid;
grid.bind(CHANGE, that._select.bind(that));
grid.table.on("dblclick" + NS, that._dblClick.bind(that));
grid.table.on("mousedown" + NS, "tr:not(.k-grid-edit-row)", that._mousedown.bind(that));
grid.table.on(KEYDOWN + NS, ".k-grid-edit-row", that._keydown.bind(that));
grid.table.on(KEYDOWN + NS, that._keydownAction.bind(that));
grid.bind("edit", function() {
that._toggleFocusable(true);
});
grid.bind("cancel", function() {
that.trigger("cancel");
});
grid.saveRow = $.noop;
Component.fn._bindEvents.call(this);
},
_kendoKeydown: function(ev) {
var that = this, current = that.grid.current(), node = current ? current.closest("tr[data-uid]") : null;
if (node && ev.keyCode === keys.ENTER && !ev.preventKendoKeydown) {
that._triggerOpen(node);
ev.preventKendoKeydown = true;
}
if (ev.keyCode === keys.F2) {
ev.preventKendoKeydown = true;
}
},
_keydownAction: function(ev) {
var that = this, target = $(ev.target).find(".k-focus").closest("tr");
if (target.length && !target.is(".k-grid-edit-row")) {
that.trigger(KEYDOWNACTION, {
target,
keyCode: ev.keyCode
});
}
},
_keydown: function(ev) {
var that = this, grid = that.grid;
if (!$(ev.target).closest(".k-grid-edit-row").length) {
return;
}
if (ev.keyCode === kendo.keys.ENTER) {
setTimeout(function() {
var editorContainer = that.grid._editContainer || $();
editorContainer.find("input").trigger("blur");
that._closeEditable();
});
that._tryCancel();
}
if (ev.keyCode === kendo.keys.ESC) {
grid.cancelChanges();
that.trigger("cancel");
}
},
_mousedown: function(ev) {
var that = this, node = $(ev.target).closest("tr[data-uid]");
if (ev.which === 1 && that.grid.editable) {
setTimeout(function() {
that._closeEditable();
});
that._tryCancel();
}
if (ev.which === 3 && !node.is(".k-selected")) {
that.grid.selectable.clear();
that.grid.select(node);
}
},
_tryCancel: function() {
var that = this, grid = that.grid, container;
if (grid.editable) {
container = grid._editContainer;
if (!container.find("input").val()) {
grid.cancelChanges();
}
}
setTimeout(function() {
that._toggleFocusable(false);
});
},
_toggleFocusable: function(state) {
var that = this, grid = that.grid;
grid.table.find("tr,td").children().addBack().toggleClass("k-focusable", state);
},
_closeEditable: function() {
var that = this, container;
if (that.grid.editable && !that.grid.editable.options.model.dirty) {
container = that.grid._editContainer;
that.grid._destroyEditable();
that.grid._displayRow(container);
that.trigger("cancel");
}
},
_select: function() {
var that = this, dataItems = that.getSelected();
that.trigger(SELECT, { entries: dataItems });
},
_dblClick: function(ev) {
var that = this, node = $(ev.target).closest("tr[data-uid]");
that._triggerOpen(node);
},
_triggerOpen: function(node) {
var that = this;
if (node.is(".k-grid-edit-row")) {
return;
}
var item = that.grid.dataItem(node);
if (item) {
that.trigger(OPEN, { entry: item });
}
},
items: function() {
let that = this, rows = that.grid.tbody.find("tr");
return rows;
},
getSelected: function() {
var that = this, items = that.grid.select(), dataItems = [];
for (var i = 0; i < items.length; i++) {
dataItems.push(that.grid.dataItem(items[i]));
}
return dataItems;
},
addFolder: function() {
this.grid.addRow();
},
edit: function(target) {
var that = this, selected = that.grid.select();
that.grid.editRow(target || selected);
},
destroy: function() {
this.grid.table.off(NS);
this.grid.element.off(NS);
Component.fn.destroy.call(this);
}
});
ui.filemanager.registerViewComponent("grid", Grid);
}
})(window.kendo.jQuery);
//#endregion
//#region ../src/filemanager/data.js
(function($, undefined) {
var kendo = window.kendo, extend = $.extend, data = kendo.data, Node = data.Node, HierarchicalDataSource = data.HierarchicalDataSource, DataSource = data.DataSource;
extend(true, kendo.data, { schemas: { "filemanager": {
data: function(data) {
return data.items || data || [];
},
model: {
id: "path",
hasChildren: "hasDirectories",
fields: {
name: {
editable: true,
type: "string",
defaultValue: "New Folder"
},
size: {
editable: false,
type: "number"
},
path: {
editable: false,
type: "string"
},
extension: {
editable: false,
type: "string"
},
isDirectory: {
editable: false,
defaultValue: true,
type: "boolean"
},
hasDirectories: {
editable: false,
defaultValue: false,
type: "boolean"
},
created: {
type: "date",
editable: false
},
createdUtc: {
type: "date",
editable: false
},
modified: {
type: "date",
editable: false
},
modifiedUtc: {
type: "date",
editable: false
}
}
}
} } });
var FileEntry = Node.define({
init: function(value) {
var that = this, isDirectory = this.isDirectory;
Node.fn.init.call(this, value);
if (typeof isDirectory === "string") {
isDirectory = kendo.getter(isDirectory);
}
if (kendo.isFunction(isDirectory)) {
var isDirectoryObject = isDirectory.call(that, that);
if (isDirectoryObject && isDirectoryObject.length === 0) {
that.isDirectory = false;
} else {
that.isDirectory = !!isDirectoryObject;
}
}
if (that.isDirectory) {
that._initChildren();
}
},
_initChildren: function() {
var that = this;
var children, transport, parameterMap;
if (!(that.children instanceof kendo.data.FileManagerDataSource)) {
children = that.children = new kendo.data.FileManagerDataSource(that._childrenOptions);
transport = children.transport;
parameterMap = transport.parameterMap;
transport.parameterMap = function(data, type) {
if (type === "read" || type === "create") {
data.target = that.id;
}
if (parameterMap) {
data = parameterMap.call(that, data, type);
}
return data;
};
children.parent = function() {
return that;
};
children.bind("change", function(e) {
e.node = e.node || that;
that.trigger("change", e);
});
children.bind("error", function(e) {
var collection = that.parent();
if (collection) {
e.node = e.node || that;
collection.trigger("error", e);
}
});
that._updateChildrenField();
}
},
isNew: function() {
if (this.fileManagerNewItem) {
delete this.fileManagerNewItem;
return true;
}
return this.id === this._defaultId;
}
});
var FileManagerDataSource = HierarchicalDataSource.extend({
init: function(options) {
var fileEntry = FileEntry.define({ children: options });
if (options.filter && !options.serverFiltering) {
this._hierarchicalFilter = options.filter;
options.filter = null;
}
DataSource.fn.init.call(this, $.extend(true, {}, { schema: {
modelBase: fileEntry,
model: fileEntry
} }, options));
this.isLocalBinding = this.transport instanceof kendo.data.LocalTransport;
this._attachBubbleHandlers();
},
insert: function(index, model) {
var parentNode = this.parent();
if (parentNode && parentNode._initChildren) {
if (model && model.isDirectory) {
parentNode.hasDirectories = true;
}
parentNode.hasChildren = true;
parentNode._initChildren();
}
return DataSource.fn.insert.call(this, index, model);
},
remove: function(node) {
var that = this, parentNode = node.parentNode(), dataSource = that, result;
if (parentNode && parentNode._initChildren) {
dataSource = parentNode.children;
}
that._cleanDestroyed(node);
result = DataSource.fn.remove.call(dataSource, node);
if (parentNode && dataSource.data() && !dataSource.data().length) {
parentNode.hasChildren = false;
} else if (parentNode && !this._hasDirectories(parentNode)) {
parentNode.hasDirectories = false;
}
return result;
},
_cleanDestroyed: function(node) {
var that = this, dataSource = that;
if (node.parentNode && node.parentNode()) {
node = node.parentNode();
dataSource = node.children;
dataSource._destroyed = [];
that._cleanDestroyed(node);
} else {
dataSource._destroyed = [];
}
},
_hasDirectories: function(node) {
var result;
if (!node.children.data()) {
return false;
}
result = node.children.data().filter(function(item) {
return item.isDirectory;
});
return !!result.length;
}
});
FileManagerDataSource.create = function(options) {
options = options && options.push ? { data: options } : options;
var dataSource = options || {}, data = dataSource.data;
if (data && data._dataSource) {
return data._dataSource;
}
dataSource.data = data;
return dataSource instanceof FileManagerDataSource ? dataSource : new FileManagerDataSource(dataSource);
};
kendo.observableFileManagerData = function(array) {
var dataSource = FileManagerDataSource.create({
data: array,
schema: kendo.data.schemas.filemanager
});
dataSource.fetch();
dataSource._data._dataSource = dataSource;
return dataSource._data;
};
extend(kendo.data, {
FileManagerDataSource,
FileEntry
});
})(window.kendo.jQuery);
//#endregion
//#region ../src/filemanager/contextmenu.js
(function($, undefined) {
var kendo = window.kendo, extend = $.extend, template = kendo.template, ContextMenu = kendo.ui.ContextMenu, ACTION = "action";
var FileManagerContextMenu = ContextMenu.extend({
init: function(element, options) {
var that = this;
ContextMenu.fn.init.call(that, element, options);
that._overrideTemplates();
that._initDefaultItems();
that._extendItems();
that.bind("select", that._onSelect.bind(that));
that.bind("open", that._onOpen.bind(that));
},
_overrideTemplates: function() {
this.templates.sprite = template(({ spriteCssClass, icon }) => {
if (spriteCssClass) {
return `<span class="${spriteCssClass}"></span>`;
}
return "";
});
},
_initDefaultItems: function() {
var that = this, messages = that.options.messages;
if (that.options.isLocalBinding) {
that.defaultItems = {};
} else {
that.defaultItems = {
"rename": {
text: messages.rename,
icon: "pencil",
command: "RenameCommand"
},
"delete": {
text: messages.delete,
icon: "trash",
command: "DeleteCommand"
}
};
}
},
events: ContextMenu.fn.events.concat([ACTION]),
_extendItems: function() {
var that = this, items = that.options.items, item, isBuiltInTool;
if (items && items.length) {
for (var i = 0; i < items.length; i++) {
item = items[i];
isBuiltInTool = $.isPlainObject(item) && Object.keys(item).length === 1 && item.name;
if (isBuiltInTool) {
item = item.name;
}
if ($.isPlainObject(item)) {
that._extendItem(item);
that.append(item);
} else if (that.defaultItems[item]) {
item = that.defaultItems[item];
that._extendItem(item);
that.append(item);
}
}
} else {
for (var key in that.defaultItems) {
item = that.defaultItems[key];
that._extendItem(item);
that.append(item);
}
}
},
_extendItem: function(item) {
var that = this, messages = that.options.messages;
extend(item, {
text: messages[item.text],
spriteCssClass: item.spriteCssClass || "",
attr: { "data-command": item.command }
});
},
_onSelect: function(ev) {
var command = $(ev.item).data("command");
var target = $(ev.target);
if (!command) {
return;
}
this.action({
command,
options: { target }
});
},
_onOpen: function(ev) {
var menu = ev.sender, items = menu.options.items;
if (!items && $.isEmptyObject(this.defaultItems)) {
ev.preventDefault();
}
},
action: function(args) {
this.trigger(ACTION, args);
}
});
extend(kendo.ui.filemanager, { ContextMenu: FileManagerContextMenu });
})(window.kendo.jQuery);
//#endregion
//#region ../src/kendo.filemanager.js
const __meta__ = {
id: "filemanager",
name: "FileManager",
category: "web",
description: "The FileManager widget displays offers file management functionality.",
depends: [
"core",
"data",
"listview",
"toolbar",
"breadcrumb",
"menu",
"treeview",
"upload",
"dialog",
"switch",
"resizable",
"selectable",
"editable",
"textbox",
"icons"
],
features: [{
id: "filemanager-grid-view",
name: "GridView",
description: "Support for GridView",
depends: ["grid"]
}]
};
(function($, undefined) {
var ui = kendo.ui, extend = $.extend, encode = kendo.htmlEncode, isPlainObject = $.isPlainObject, isArray = Array.isArray, DataBoundWidget = ui.DataBoundWidget, template = kendo.template, outerHeight = kendo._outerHeight, ns = ".kendoFileManager", NAVIGATE = "navigate", SELECT = "select", OPEN = "open", ERROR = "error", CHANGE = "change", UPLOAD = "upload", SUCCESS = "success", CLICK = "click", TOGGLE = "toggle", CLOSE = "close", HIDE = "hide", LOAD = "load", DATABINDING = "dataBinding", DATABOUND = "dataBound", DROP = "drop", EXECUTE = "execute", COMMAND = "command", KEYDOWNACTION = "keydownAction", CANCEL = "cancel", TREE_TYPE = "tree", DOT = ".";
var fileManagerStyles = {
wrapper: "k-widget k-filemanager",
header: "k-filemanager-header",
navigation: "k-filemanager-navigation",
contentContainer: "k-filemanager-content-container",
content: "k-filemanager-content",
preview: "k-filemanager-preview",
toolbar: "k-filemanager-toolbar",
treeview: "k-filemanager-treeview",
breadcrumb: "k-filemanager-breadcrumb",
view: "k-filemanager-view",
grid: "k-filemanager-grid",
list: "k-filemanager-listview",
upload: "k-filemanager-upload",
uploadDialog: "k-filemanager-upload-dialog",
splitBar: "k-splitbar",
splitBarHorizontal: "k-splitbar-horizontal k-splitbar-draggable-horizontal",
splitBarHover: "k-splitbar-horizontal-hover",
splitBarIcon: "k-icon k-resize-handle",
splitBarNavigation: "k-filemanager-splitbar-navigation",
splitBarPreview: "k-filemanager-splitbar-preview",
resizable: "k-filemanager-resizable"
};
var fileManagerTemplateStyles = {
filePreview: "k-file-preview",
fileInfo: "k-file-info",
fileName: "k-file-name",
fileMeta: "k-file-meta",
metaLabel: "k-file-meta-label",
metaValue: "k-file-meta-value",
extension: "k-file-type",
size: "k-file-size",
created: "k-file-created",
modified: "k-file-modified"
};
var viewTypes = {
grid: "grid",
list: "list"
};
var NO_FILE_PREVIEW_TEMPLATE = ({ styles, messages }) => `<div class="${encode(styles.fileInfo)}">` + `<div class="${encode(styles.filePreview)}">` + "<span class=\"k-file-icon k-icon k-svg-icon k-i-none\" aria-hidden=\"true\"></span>" + "</div>" + `<span class="${encode(styles.fileName)}" k-no-file-selected>${encode(messages.noFileSelected)}</span>` + "</div>";
var SINGLE_FILES_PREVIEW_TEMPLATE = ({ styles, selection, metaFields, messages }) => {
let result = "";
result += `<div class="${encode(styles.fileInfo)}">` + `<div class="${encode(styles.filePreview)}">` + kendo.ui.icon({
icon: !selection[0].isDirectory ? encode(kendo.getFileGroup(selection[0].extension, true)) : "folder",
iconClass: "k-file-icon",
size: "xxxlarge"
}) + "</div>" + `<span class="${encode(styles.fileName)}">${encode(selection[0].name)}</span>`;
if (metaFields) {
result += `<dl class="${encode(styles.fileMeta)}">`;
for (var i = 0; i < metaFields.length; i += 1) {
var field = metaFields[i];
result += `<dt class="${encode(styles.metaLabel)}">${encode(messages[field])}: </dt>` + `<dd class="${encode(styles.metaValue)} ${encode(styles[field])}">`;
if (field == "size") {
result += ` ${encode(kendo.getFileSizeMessage(selection[0][field]))}`;
} else if (selection[0][field] instanceof Date) {
result += ` ${encode(kendo.toString(selection[0][field], "G"))}`;
} else if (field == "extension") {
result += ` ${encode(!selection[0].isDirectory ? kendo.getFileGroup(selection[0].extension) : "folder")}`;
} else {
result += ` ${encode(selection[0][field])}`;
}
result += "</dd>" + "<dd class=\"k-line-break\"></dd>";
}
result += "</dl>";
}
result += "</div>";
return result;
};
var MULTIPLE_FILES_PREVIEW_TEMPLATE = ({ styles, selection, messages }) => `<div class="${encode(styles.fileInfo)}">` + `<div class="${encode(styles.filePreview)}">` + kendo.ui.icon({
icon: "file",
iconClass: "k-file-icon",
size: "xxxlarge"
}) + "</div>" + `<span class="${encode(styles.fileName)}">` + `${encode(selection.length)} ` + `${encode(messages.items)}` + "</span>" + "</div>";
var FileManager = DataBoundWidget.extend({
init: function(element, options) {
var that = this;
DataBoundWidget.fn.init.call(that, element, options);
that.options = kendo.deepExtend({}, that.options, options);
that.defaultSortOption = {
field: "name",
dir: "asc"
};
that.folderSortOption = {
field: "isDirectory",
dir: "desc"
};
that._commandStack = new ui.filemanager.CommandStack();
that._dataSource();
that._wrapper();
that._renderHeader();
that._renderContentContainer();
that._initContextMenu();
that._renderNavigation();
that._renderContent();
that._renderPreview();
that._initUploadDialog();
that._resizable();
that._attachKeyDown();
that.resize();
kendo.notify(that, kendo.ui);
},
options: {
name: "FileManager",
height: 500,
resizable: true,
initialView: viewTypes.list,
toolbar: { resizable: true },
contextMenu: {},
upload: {},
uploadUrl: "",
views: {},
breadcrumb: {},
draggable: true,
dialogs: {
upload: { width: 530 },
moveConfirm: {
width: 350,
closable: true
},
deleteConfirm: {
width: 360,
closable: true
},
renamePrompt: {
width: 350,
closable: true
}
},
previewPane: {
metaFields: [
"extension",
"size",
"created",
"modified"
],
noFileTemplate: NO_FILE_PREVIEW_TEMPLATE,
singleFileTemplate: SINGLE_FILES_PREVIEW_TEMPLATE,
multipleFilesTemplate: MULTIPLE_FILES_PREVIEW_TEMPLATE
},
messages: {
toolbar: {
createFolder: "New Folder",
upload: "Upload",
sortDirection: "Sort Direction",
sortDirectionAsc: "Sort Direction Ascending",
sortDirectionDesc: "Sort Direction Descending",
sortField: "Sort By",
nameField: "Name",
sizeField: "File Size",
typeField: "Type",
dateModifiedField: "Date Modified",
dateCreatedField: "Date Created",
listView: "List View",
gridView: "Grid View",
search: "Search",
details: "View Details",
detailsChecked: "On",
detailsUnchecked: "Off",
"delete": "Delete",
rename: "Rename"
},
views: {
nameField: "Name",
sizeField: "File Size",
typeField: "Type",
dateModifiedField: "Date Modified",
dateCreatedField: "Date Created",
items: "items",
listLabel: "FileManager ListView",
gridLabel: "FileManager Grid",
treeLabel: "FileManager TreeView"
},
dialogs: {
upload: {
title: "Upload Files",
clear: "Clear List",
done: "Done"
},
moveConfirm: {
title: "Confirm",
content: "<p class='k-text-center'>Do you want to move or copy?</p>",
okText: "Copy",
cancel: "Move",
close: "close"
},
deleteConfirm: {
title: "Confirm",
content: "<p class='k-text-center'>Are you sure you want to delete the selected file(s)?</br>You cannot undo this action.</p>",
okText: "Delete",
cancel: "Cancel",
close: "close"
},
renamePrompt: {
title: "Prompt",
content: "<p class='k-text-center'>Enter new name for the file.</p>",
okText: "Rename",
cancel: "Cancel",
close: "close"
}
},
previewPane: {
noFileSelected: "No File Selected",
extension: "Type",
size: "Size",
created: "Date Created",
createdUtc: "Date Created UTC",
modified: "Date Modified",
modifiedUtc: "Date Modified UTC",
items: "items"
}
}
},
events: [
NAVIGATE,
SELECT,
OPEN,
DATABINDING,
DATABOUND,
ERROR,
DROP,
EXECUTE,
COMMAND
],
defaultTools: {
createFolder: {
type: "button",
name: "createFolder",
command: "CreateFolderCommand",
rules: { remote: true }
},
upload: {
type: "button",
name: "upload",
command: "OpenDialogCommand",
options: "{ \"type\": \"uploadDialog\" }",
rules: { remote: true }
},
sortDirection: {
type: "buttonGroup",
buttons: [{
name: "sortDirectionAsc",
showText: "overflow",
icon: "sort-asc-small",
togglable: true,
group: "sortDirection",
command: "SortCommand",
options: "{ \"dir\": \"asc\" }",
selected: true
}, {
name: "sortDirectionDesc",
showText: "overflow",
icon: "sort-desc-small",
togglable: true,
group: "sortDirection",
command: "SortCommand",
options: "{ \"dir\": \"desc\" }"
}]
},
sortField: {
type: "splitButton",
name: "sortField",
command: "SortCommand",
menuButtons: [
{
name: "nameField",
options: "{\"field\": \"name\"}",
command: "SortCommand"
},
{
name: "typeField",
options: "{\"field\": \"extension\"}",
command: "SortCommand"
},
{
name: "sizeField",
options: "{\"field\": \"size\"}",
command: "SortCommand"
},
{
name: "dateCreatedField",
options: "{\"field\": \"created\"}",
command: "SortCommand"
},
{
name: "dateModifiedField",
options: "{\"field\": \"modified\"}",
command: "SortCommand"
}
]
},
changeView: {
type: "buttonGroup",
buttons: [{
name: "gridView",
showText: "overflow",
icon: "grid",
togglable: true,
group: "changeView",
command: "ChangeViewCommand",
options: "grid"
}, {
name: "listView",
showText: "overflow",
icon: "grid-layout",
togglable: true,
group: "changeView",
command: "ChangeViewCommand",
options: "list"
}]
},
spacer: { type: "spacer" },
details: {
type: "component",
name: "details",
items: [{
template: function(data) {
return "<label for='details-toggle'>" + encode(data.componentOptions.messages.text) + "</label>";
},
overflow: "never",
componentOptions: { messages: { text: "details" } }
}, {
name: "details",
command: "TogglePaneCommand",
options: "{ \"type\": \"preview\" }",
overflow: "never",
element: "<input id='details-toggle' class='k-filemanager-details-toggle' />",
component: "Switch",
componentOptions: {
messages: {
checked: "detailsChecked",
unchecked: "detailsUnchecked"
},
commandOn: "change"
}
}]
},
search: {
type: "component",
name: "search",
command: "SearchCommand",
options: "{ \"field\": \"name\", \"operator\": \"startswith\" }",
overflow: "never",
component: "TextBox",
componentOptions: {
placeholder: "search",
icon: "search",
commandOn: "input"
}
}
},
_attachKeyDown: function() {
var that = this;
that.wrapper.on("keydown" + ns, (e) => {
if (e.keyCode === kendo.keys.F10) {
e.preventDefault();
that.toolbar.element.find("[tabindex=0]").first().trigger("focus");
}
});
},
_dataSource: function() {
var that = this, options = that.options, dataSourceOptions = options.dataSource || {}, typeSortOrder = that.folderSortOption, nameSortOrder = that.defaultSortOption, dataSource;
if (!(dataSourceOptions instanceof kendo.data.FileManagerDataSource)) {
if (isArray(dataSourceOptions)) {
dataSource = {
data: dataSourceOptions,
autoSync: false,
sort: [typeSortOrder, nameSortOrder]
};
} else {
dataSource = extend(true, dataSourceOptions, {
autoSync: false,
sort: [typeSortOrder, nameSortOrder]
});
}
if (dataSourceOptions && isPlainObject(dataSourceOptions.schema)) {
dataSource.schema = dataSourceOptions.schema;
} else if (isPlainObject(kendo.data.schemas.filemanager)) {
dataSource.schema = kendo.data.schemas.filemanager;
}
} else {
dataSource = dataSourceOptions;
}
if (that.dataSource && that._errorHandler) {
that.dataSource.unbind(ERROR, that._errorHandler);
that.dataSource.unbind(CHANGE, that._changeHandler);
} else {
that._errorHandler = that._error.bind(that);
that._changeHandler = that._change.bind(that);
}
that.dataSource = kendo.data.FileManagerDataSource.create(dataSource).bind(ERROR, that._errorHandler).bind(CHANGE, that._changeHandler);
},
_error: function(ev) {