js-fileexplorer

repository·master·Indexed 43 days ago

https://github.com/cubiclesoft/js-fileexplorer

A zero-dependency, pure JavaScript widget for navigating, managing, uploading, and downloading hierarchical object structures such as files, folders, or JSON/XML in modern web browsers. Version 1.0.0 includes a PHP server-side helper class, FileExplorerFSHelper, for physical file system integration and a DebounceAttributes class for efficient attribute monitoring.

Tokens
21.3K
Snippets
53
Records
86
Agent score
54%

What's inside js-fileexplorer

  1. Use the DebounceAttributes class for efficient attribute watching

    master

    The DebounceAttributes class provides a performant alternative to traditional DOM event debouncing. Instead of listening to events, it monitors specific attribute values of elements at a set interval. It is particularly useful for tracking properties like offsetWidth or scrollLeft that don't always trigger reliable events or where you want to avoid the overhead of high-frequency event listeners.

    To use it, instantiate the class with an options object and call .Start() to begin the monitoring process.

    var statusbarresizewatch = new DebounceAttributes({
    	watchers: [
    		{ elem: elems.mainwrap, attr: 'offsetWidth', val: -1 }
    	],
    	interval: 50,
    	stopsame: 5,
    	callback: CalculateUpdateMultilineStatus,
    	intervalcallback: CalculateUpdateMultilineStatus
    });
    
    window.addEventListener('resize', statusbarresizewatch.Start, true);
  2. How file actions are processed internally

    master

    The FileExplorerFSHelper class contains several protected static methods that implement specific file management actions. These are typically invoked via HandleActions().

    Common Action Handlers

    ActionMethodKey Request Parameters
    RefreshProcessRefreshActionpath (JSON array of path IDs)
    ThumbnailProcessThumnailActionpath (JSON array of path IDs), id (image filename)
    RenameProcessRenameActionpath, id (old name), newname
    New FolderProcessNewFolderActionpath, name (optional)
    New FileProcessNewFileActionpath
    UploadProcessUploadActionpath, name, size, queuestarted, currpath
    DownloadProcessDownloadActionpath, ids (JSON array of files/dirs)
    MoveProcessMoveActionsrcpath, srcids, destpath
    DeleteProcessDeleteActionsrcpath, srcids (moves to recycling bin if enabled)
    RecycleProcessRecycleActionsrcpath, srcids

    Complex Operations

    Copying Files

    Copying is a multi-stage process to allow for UI progress updates:

    1. Initialization (ProcessCopyInitAction): Calculates how many files will be overwritten and sets up progress tracking. Returns a copykey.
    2. Execution (ProcessCopyAction): Uses the copykey to perform the actual copy. In multiple-request mode, it runs for a few seconds and returns updated progress information.

    Uploading Files

    ProcessUploadAction handles both the initialization and the actual upload. It uses the currpath to determine if the newly uploaded entry should be included in the response to update the current view.

  3. Understand the Folder class concept

    master

    The Folder class is an internal abstraction used by FileExplorer to track the contents of a specific path.

    Key constraints:

    • You cannot instantiate the Folder class directly using new Folder(). It is instantiated only by the FileExplorer class.
    • You access Folder instances primarily through callbacks provided by FileExplorer methods.
    • Each Folder instance manages its own set of entries (files and subfolders), attributes, and event listeners.
  4. Use progress trackers for long-running operations

    master

    For operations like copying or uploading, use CreateProgressTracker to provide visual feedback in the status bar.

    Workflow:

    1. Call CreateProgressTracker(cancelcallback) to get a tracker object.
    2. Periodically update the tracker's properties (e.g., totalbytes, itemsdone, faileditems, queueditems).
    3. The status bar automatically updates every second via UpdateProgressText().
    4. Call RemoveProgressTracker(tracker, finishmessage) when the operation is complete. If it's the last tracker, you can provide a finishmessage to display.

    Tracker Properties:

    • totalbytes: Total bytes to transfer.
    • itemsdone: Number of successfully processed items.
    • faileditems: Number of failed items.
    • queueditems: Number of items in the queue.
    • showbyterate: Boolean to show byte rate after 3 seconds.
    • finishmessage: Message to show in the status bar when the tracker is removed.
    const tracker = fe.CreateProgressTracker(() => {
      console.log('User cancelled the operation');
    });
    
    // Simulate progress
    tracker.totalbytes = 1024 * 1024;
    tracker.itemsdone = 5;
    
    // Later, remove it
    fe.RemoveProgressTracker(tracker, 'Operation Complete');
  5. Use the TextareaOverlay class

    master

    The TextareaOverlay class displays a positionable textarea with text selection support. It provides full keyboard, mouse, and touch support, making it suitable for in-place text editing within a file explorer interface.

    To use it, instantiate it via new window.FileExplorer.TextareaOverlay(parentelem, options).

    options = {
    	initvalue: 'hello.txt',
    	initselstart: 0,
    	initselend: 5,
    
    	onposition: function(textelem) {
    		textelem.style.left = 50 + 'px';
    		extelem.style.top = 40 + 'px';
    		extelem.style.width = 50 + 'px';
    		extelem.style.height = Math.min(elem.offsetHeight - 2, elem.scrollHeight - 42, textelem.scrollHeight + 2) + 'px';
    	},
    
    	ondone: function(val, lastelem) {
    		if (lastelem)  lastelem.focus();
    		console.log(val);
    
    		this.Destroy();
    	},
    
    	oncancel: function(lastelem) {
    		if (lastelem)  lastelem.focus();
    
    		this.Destroy();
    	},
    };
    
    var textoverlaytest = new window.FileExplorer.TextareaOverlay(elem, options);
  6. Use the FileExplorerFSHelper PHP class

    master

    The FileExplorerFSHelper class is a server-side PHP helper designed to bridge the FileExplorer JavaScript widget with a physical file system. It handles common server-side actions such as directory listings, file uploads, renaming, moving, and deleting files.

    Key Requirements

    • Permissions: The directories used for files (e.g., /files/) and thumbnails (e.g., /thumbs/) must be writable by the web server user (e.g., www-data).
    • Maintenance: It is recommended to run a nightly cron job to clear out .tmp files (failed/abandoned uploads), old files in the recycling bin, and old thumbnail directories.

    Implementation Pattern

    To handle file explorer actions, use the FileExplorerFSHelper::HandleActions method. This method requires an action name prefix, a base directory path, and a configuration options array.

    <?php
    require_once "server-side-helpers/file_explorer_fs_helper.php";
    
    $options = array(
        "base_url" => "https://cubiclesoft.com/myapp/files/",
        "protect_depth" => 1,
        "recycle_to" => "Recycle Bin",
        "temp_dir" => "/tmp",
        "dot_folders" => false,
        "allowed_exts" => ".jpg, .jpeg, .png, .gif, .svg, .txt",
        "allow_empty_ext" => true,
        "thumbs_dir" => "/var/www/myapp/thumbs",
        "thumbs_url" => "https://cubiclesoft.com/myapp/thumbs/",
        "thumb_create_url" => "https://cubiclesoft.com/myapp/?action=file_explorer_thumbnail&xsrftoken=qwerasdf",
        "refresh" => true,
        "rename" => true,
        "file_info" => false,
        "load_file" => false,
        "save_file" => false,
        "new_folder" => true,
        "new_file" => ".txt",
        "upload" => true,
        "upload_limit" => 20000000,
        "download" => "user123-" . date("Y-m-d_H-i-s") . ".zip",
        "download_module" => "",
        "download_module_prefix" => "",
        "copy" => true,
        "move" => true,
        "recycle" => true,
        "delete" => true
    );
    
    // Handle actions with prefix 'file_explorer_' in the directory '/var/www/myapp/files'
    FileExplorerFSHelper::HandleActions("action", "file_explorer_", "/var/www/myapp/files", $options);
    ?>
  7. Use the ImageLoader class for delayed image loading

    master

    The ImageLoader class is a multi-queue delayed image loader. It allows you to queue multiple image URLs and control exactly when the loading process begins. This is useful for preventing browser congestion by limiting the number of simultaneous image requests.

    function ImageLoadResult(opts, success)
    {
    	console.log(opts);
    	console.log(success);
    }
    
    var imageloader = new ImageLoader();
    
    imageloader.AddToQueue({
    	src: 'https://picsum.photos/300/200',
    	callback: ImageLoadResult,
    	info: { id: 'cool' }
    });
    
    imageloader.AddToQueue({
    	src: 'https://picsum.photos/150/400',
    	callback: ImageLoadResult,
    	info: { id: 'cool2' }
    });
    
    // Start processing the queued images
    imageloader.ProcessQueue();
  8. Install and load js-fileexplorer

    master

    To use the widget, download or clone the repository and place the file-explorer directory on your server. Include the CSS and JavaScript files in your HTML page:

    <link rel="stylesheet" type="text/css" href="file-explorer/file-explorer.css">
    <script type="text/javascript" src="file-explorer/file-explorer.js"></script>
    <link rel="stylesheet" type="text/css" href="file-explorer/file-explorer.css">
    <script type="text/javascript" src="file-explorer/file-explorer.js"></script>
  9. How to create custom toolbar tools

    master

    You can extend the widget by registering custom tools. A tool is a function that receives the FileExplorer instance.

    Steps to build a tool:

    1. Define a function that accepts the fe (FileExplorer) instance.
    2. Use fe.AddToolbarButton(cssClass, label) to add a button to the UI.
    3. Listen for the update_tool event to manage the button's enabled/disabled state based on the current folder context and selection.
    4. Listen for the destroy event to clean up event listeners.
    5. Register the tool using window.FileExplorer.RegisterTool(groupIndex, ToolClass).

    Example: A simple Delete tool implementation

    (function() {
    	var FileExplorerTool_Delete = function(fe) {
    		if (!(this instanceof FileExplorerTool_Delete)) return new FileExplorerTool_Delete(fe);
    
    		if (!fe.hasEventListener('delete') && !fe.settings.tools.delete) return;
    
    		var enabled = false;
    		var node = fe.AddToolbarButton('fe_fileexplorer_folder_tool_delete', fe.Translate('Delete (Del)'));
    
    		var ClickHandler = function(e) {
    			if (e.isTrusted && enabled) fe.DeleteSelectedItems(!e.shiftKey);
    		};
    
    		node.addEventListener('click', ClickHandler);
    
    		var UpdateToolHandler = function(currfolder, attrs) {
    			var prevenabled = enabled;
    			enabled = (!currfolder.waiting && (!('canmodify' in attrs) || attrs.canmodify) && fe.GetNumSelectedItems());
    
    			if (preenabled !== enabled) {
    				if (enabled) node.classList.remove('fe_fileexplorer_disabled');
    				else node.classList.add('fe_fileexplorer_disabled');
    				fe.ToolStateUpdated();
    			}
    		};
    
    		fe.addEventListener('update_tool', UpdateToolHandler);
    
    		var DestroyToolHandler = function() {
    			node.removeEventListener('click', ClickHandler);
    		};
    
    		fe.addEventListener('destroy', DestroyToolHandler);
    	};
    
    	window.FileExplorer.RegisterTool(1, FileExplorerTool_Delete);
    })();
  10. Initialize the FileExplorer widget

    master

    To create a new File Explorer instance, use the FileExplorer constructor. It must be called with the new keyword. You must provide a parent DOM node where the widget will be appended and an options object for configuration.

    const container = document.getElementById('explorer-container');
    const options = { /* your configuration options */ };
    const fe = new FileExplorer(container, options);
    const fe = new FileExplorer(parentelem, options);
  11. Handle file upload events with init_upload and upload_done

    master

    The file explorer uses a custom event system to manage the lifecycle of file uploads. You can listen for these events to integrate with your own backend or UI.

    init_upload

    Triggered when an upload process is being initialized. Arguments:

    • startuploadcallback: A function (process) => void where process is true to proceed or a string error message to fail.
    • fileinfo: The object containing file metadata and progress.
    • uploadqueuestarted: Timestamp of when the first upload in the queue started.

    upload_done

    Triggered when a file upload is successfully completed. Arguments:

    • finalizecallback: A function (success, entry) => void used to finalize the entry in the UI.
    • fileinfo: The object containing the file metadata.

    upload_error

    Triggered when an upload fails. Arguments:

    • fileinfo: The object containing the file metadata.
    • error: The error object/event.
  12. Configure FileExplorer handler availability

    master

    You can enable or disable specific file operations by setting their corresponding boolean keys in the configuration:

    • refresh (boolean): Enables the refresh handler (Recommended to keep true).
    • rename (boolean): Enables the rename handler.
    • file_info (boolean): Enables the file information handler.
    • load_file (boolean): Enables file retrieval (useful for editors).
    • save_file (boolean): Enables file saving (useful for editors).
    • new_folder (boolean): Enables the new folder handler.
    • new_file (string|boolean): The extension to use for new files, or false to disable.
    • copy (boolean): Enables copy_init and copy handlers.
    • move (boolean): Enables the move handler.
    • recycle (boolean): Enables the recycle handler.
    • delete (boolean): Enables the delete handler.