DevExtreme v24.1 is now available.

Explore our newest features/capabilities and share your thoughts with us.

Your search did not match any results.

Overview

The DevExtreme JavaScript FileManager component allows you to display and manage files and directories for different file systems. The FileManager uses file system providers to access file systems.

Use the fileSystemProvider property to configure the component's file system provider. The "File System Types" demo group illustrates how to use the FileManager with different file system providers.

Backend API
import React, { useCallback, useState } from 'react'; import FileManager, { FileManagerTypes, Permissions } from 'devextreme-react/file-manager'; import RemoteFileSystemProvider from 'devextreme/file_management/remote_provider'; import { Popup } from 'devextreme-react/popup'; const remoteProvider = new RemoteFileSystemProvider({ endpointUrl: 'https://js.devexpress.com/Demos/Mvc/api/file-manager-file-system-images', }); export default function App() { const [currentPath, setCurrentPath] = useState('Widescreen'); const [popupVisible, setPopupVisible] = useState(false); const [imageItemToDisplay, setImageItemToDisplay] = useState<{ name?: string, url?: string }>({}); const displayImagePopup = useCallback((e: FileManagerTypes.SelectedFileOpenedEvent) => { setPopupVisible(true); setImageItemToDisplay({ name: e.file.name, url: e.file.dataItem.url, }); }, [setPopupVisible, setImageItemToDisplay]); const hideImagePopup = useCallback(() => { setPopupVisible(false); }, [setPopupVisible]); const onCurrentDirectoryChanged = useCallback((e: FileManagerTypes.CurrentDirectoryChangedEvent) => { setCurrentPath(e.component.option('currentPath')); }, [setCurrentPath]); return ( <div> <FileManager currentPath={currentPath} fileSystemProvider={remoteProvider} onSelectedFileOpened={displayImagePopup} onCurrentDirectoryChanged={onCurrentDirectoryChanged}> <Permissions create={true} copy={true} move={true} delete={true} rename={true} upload={true} download={true}> </Permissions> </FileManager> <Popup maxHeight={600} hideOnOutsideClick={true} showCloseButton={true} title={imageItemToDisplay.name} visible={popupVisible} onHiding={hideImagePopup} className="photo-popup-content"> <img src={imageItemToDisplay.url} className="photo-popup-image" /> </Popup> </div> ); }
import React, { useCallback, useState } from 'react'; import FileManager, { Permissions } from 'devextreme-react/file-manager'; import RemoteFileSystemProvider from 'devextreme/file_management/remote_provider'; import { Popup } from 'devextreme-react/popup'; const remoteProvider = new RemoteFileSystemProvider({ endpointUrl: 'https://js.devexpress.com/Demos/Mvc/api/file-manager-file-system-images', }); export default function App() { const [currentPath, setCurrentPath] = useState('Widescreen'); const [popupVisible, setPopupVisible] = useState(false); const [imageItemToDisplay, setImageItemToDisplay] = useState({}); const displayImagePopup = useCallback( (e) => { setPopupVisible(true); setImageItemToDisplay({ name: e.file.name, url: e.file.dataItem.url, }); }, [setPopupVisible, setImageItemToDisplay], ); const hideImagePopup = useCallback(() => { setPopupVisible(false); }, [setPopupVisible]); const onCurrentDirectoryChanged = useCallback( (e) => { setCurrentPath(e.component.option('currentPath')); }, [setCurrentPath], ); return ( <div> <FileManager currentPath={currentPath} fileSystemProvider={remoteProvider} onSelectedFileOpened={displayImagePopup} onCurrentDirectoryChanged={onCurrentDirectoryChanged} > <Permissions create={true} copy={true} move={true} delete={true} rename={true} upload={true} download={true} ></Permissions> </FileManager> <Popup maxHeight={600} hideOnOutsideClick={true} showCloseButton={true} title={imageItemToDisplay.name} visible={popupVisible} onHiding={hideImagePopup} className="photo-popup-content" > <img src={imageItemToDisplay.url} className="photo-popup-image" /> </Popup> </div> ); }
import React from 'react'; import ReactDOM from 'react-dom'; import App from './App.tsx'; ReactDOM.render( <App />, document.getElementById('app'), );
window.exports = window.exports || {}; window.config = { transpiler: 'ts', typescriptOptions: { module: 'system', emitDecoratorMetadata: true, experimentalDecorators: true, jsx: 'react', }, meta: { 'react': { 'esModule': true, }, 'typescript': { 'exports': 'ts', }, 'devextreme/time_zone_utils.js': { 'esModule': true, }, 'devextreme/localization.js': { 'esModule': true, }, 'devextreme/viz/palette.js': { 'esModule': true, }, }, paths: { 'npm:': 'https://unpkg.com/', }, defaultExtension: 'js', map: { 'ts': 'npm:plugin-typescript@4.2.4/lib/plugin.js', 'typescript': 'npm:typescript@4.2.4/lib/typescript.js', 'react': 'npm:react@17.0.2/umd/react.development.js', 'react-dom': 'npm:react-dom@17.0.2/umd/react-dom.development.js', 'prop-types': 'npm:prop-types@15.8.1/prop-types.js', 'rrule': 'npm:rrule@2.6.4/dist/es5/rrule.js', 'luxon': 'npm:luxon@1.28.1/build/global/luxon.min.js', 'es6-object-assign': 'npm:es6-object-assign@1.1.0', 'devextreme': 'npm:devextreme@24.1.3/cjs', 'devextreme-react': 'npm:devextreme-react@24.1.3/cjs', 'jszip': 'npm:jszip@3.10.1/dist/jszip.min.js', 'devextreme-quill': 'npm:devextreme-quill@1.7.1/dist/dx-quill.min.js', 'devexpress-diagram': 'npm:devexpress-diagram@2.2.8/dist/dx-diagram.js', 'devexpress-gantt': 'npm:devexpress-gantt@4.1.56/dist/dx-gantt.js', '@devextreme/runtime': 'npm:@devextreme/runtime@3.0.13', 'inferno': 'npm:inferno@7.4.11/dist/inferno.min.js', 'inferno-compat': 'npm:inferno-compat/dist/inferno-compat.min.js', 'inferno-create-element': 'npm:inferno-create-element@7.4.11/dist/inferno-create-element.min.js', 'inferno-dom': 'npm:inferno-dom/dist/inferno-dom.min.js', 'inferno-hydrate': 'npm:inferno-hydrate@7.4.11/dist/inferno-hydrate.min.js', 'inferno-clone-vnode': 'npm:inferno-clone-vnode/dist/inferno-clone-vnode.min.js', 'inferno-create-class': 'npm:inferno-create-class/dist/inferno-create-class.min.js', 'inferno-extras': 'npm:inferno-extras/dist/inferno-extras.min.js', 'devextreme-cldr-data': 'npm:devextreme-cldr-data@1.0.3', // SystemJS plugins 'plugin-babel': 'npm:systemjs-plugin-babel@0.0.25/plugin-babel.js', 'systemjs-babel-build': 'npm:systemjs-plugin-babel@0.0.25/systemjs-babel-browser.js', // Prettier 'prettier/standalone': 'npm:prettier@2.8.8/standalone.js', 'prettier/parser-html': 'npm:prettier@2.8.8/parser-html.js', }, packages: { 'devextreme': { defaultExtension: 'js', }, 'devextreme-react': { main: 'index.js', }, 'devextreme/events/utils': { main: 'index', }, 'devextreme/localization/messages': { format: 'json', defaultExtension: 'json', }, 'devextreme/events': { main: 'index', }, 'es6-object-assign': { main: './index.js', defaultExtension: 'js', }, }, packageConfigPaths: [ 'npm:@devextreme/*/package.json', 'npm:@devextreme/runtime@3.0.13/inferno/package.json', ], babelOptions: { sourceMaps: false, stage0: true, react: true, }, }; System.config(window.config);
import React from 'react'; import ReactDOM from 'react-dom'; import App from './App.js'; ReactDOM.render(<App />, document.getElementById('app'));
<!DOCTYPE html> <html lang="en"> <head> <title>DevExtreme Demo</title> <meta http-equiv="X-UA-Compatible" content="IE=edge" /> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=5.0" /> <link rel="stylesheet" type="text/css" href="https://cdn3.devexpress.com/jslib/24.1.3/css/dx.light.css" /> <link rel="stylesheet" type="text/css" href="https://cdn3.devexpress.com/jslib/24.1.3/css/dx-gantt.min.css" /> <link rel="stylesheet" type="text/css" href="styles.css" /> <script src="https://unpkg.com/core-js@2.6.12/client/shim.min.js"></script> <script src="https://unpkg.com/systemjs@0.21.3/dist/system.js"></script> <script type="text/javascript" src="config.js"></script> <script type="text/javascript"> System.import("./index.tsx"); </script> </head> <body class="dx-viewport"> <div class="demo-container"> <div id="app"></div> </div> </body> </html>
.photo-popup-content { text-align: center; } .photo-popup-content .photo-popup-image { height: 100%; max-width: 100%; }
using DevExtreme.AspNet.Mvc.FileManagement; using System; using System.IO; using System.Net.Http; using System.Net.Http.Headers; using System.Web; using System.Web.Hosting; using System.Web.Http; using System.Web.Mvc; namespace DevExtreme.MVC.Demos.Controllers.ApiControllers { public class FileManagerImagesApiController : ApiController { static readonly string SampleImagesRelativePath = Path.Combine("Content", "SampleData", "SampleImages"); [System.Web.Http.AcceptVerbs("GET", "POST")] [System.Web.Http.Route("api/file-manager-file-system-images", Name = "FileManagementImagesApi")] public object FileSystem() { var request = new HttpContextWrapper(HttpContext.Current).Request; FileSystemCommand command; Enum.TryParse(request["command"], out command); string arguments = request["arguments"]; var config = new FileSystemConfiguration { Request = request, FileSystemProvider = new PhysicalFileSystemProvider( Path.Combine(HostingEnvironment.ApplicationPhysicalPath, SampleImagesRelativePath), (fileSystemItem, clientItem) => { if(!clientItem.IsDirectory) clientItem.CustomFields["url"] = GetFileItemUrl(fileSystemItem); } ), //uncomment the code below to enable file/directory management //AllowCopy = true, //AllowCreate = true, //AllowMove = true, //AllowDelete = true, //AllowRename = true, //AllowUpload = true, AllowDownload = true, TempDirectory = HttpContext.Current.Server.MapPath("~/App_Data/UploadTemp") }; var processor = new FileSystemCommandProcessor(config); var commandResult = processor.Execute(command, arguments); var result = commandResult.GetClientCommandResult(); return command == FileSystemCommand.Download && commandResult.Success ? CreateDownloadResponse(result) : Request.CreateResponse(result); } string GetFileItemUrl(FileSystemInfo fileSystemItem) { var relativeUrl = "~/" + fileSystemItem.FullName .Replace(HostingEnvironment.ApplicationPhysicalPath, "") .Replace(Path.DirectorySeparatorChar, '/'); return Url.Content(relativeUrl); } HttpResponseMessage CreateDownloadResponse(object result) { var fileContent = result as FileStreamResult; if(fileContent == null) return Request.CreateResponse(result); var response = new HttpResponseMessage() { Content = new StreamContent(fileContent.FileStream) }; response.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment") { FileName = fileContent.FileDownloadName }; response.Content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream"); return response; } } }

The component's default security settings provide read-only access to files and directories. Use the permissions property to deny or allow a user to copy, create, move, delete, rename, upload, and download files and directories. You can also specify file restrictions: allowed file extensions (allowedFileExtensions), chunk size (chunkSize) and maximum file size (maxFileSize).

Use the component's itemView property or the view switcher on the toolbar to display file system items as a detailed list or customizable thumbnails.

This demo contains commented out code lines that enable file modification operations. You can uncomment them and configure if necessary.