DevExtreme v24.1 is now available.

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

Your search did not match any results.

Async Upload

In this demo, the FileUploader component is configured for asynchronous upload. Use the File types drop-down menu to select acceptable file types for the Open file dialog. The Upload mode drop-down menu allows you to specify whether the file is uploaded on a button click or instantly after the file has been selected. In addition, you can specify whether the FileUploader allows multiple file selection.

Backend API
import React, { useCallback, useState } from 'react'; import FileUploader, { FileUploaderTypes } from 'devextreme-react/file-uploader'; import SelectBox, { SelectBoxTypes } from 'devextreme-react/select-box'; import CheckBox, { CheckBoxTypes } from 'devextreme-react/check-box'; const uploadModes = ['instantly', 'useButtons']; const fileTypeLabel = { 'aria-label': 'File Type' }; const uploadModeLabel = { 'aria-label': 'Mode' }; const fileTypesSource = [ { name: 'All types', value: '*' }, { name: 'Images', value: 'image/*' }, { name: 'Videos', value: 'video/*' }, ]; export default function App() { const [multiple, setMultiple] = useState(false); const [uploadMode, setUploadMode] = useState<FileUploaderTypes.Properties['uploadMode']>('instantly'); const [accept, setAccept] = useState('*'); const [selectedFiles, setSelectedFiles] = useState([]); const onSelectedFilesChanged = useCallback((e: FileUploaderTypes.ValueChangedEvent) => { setSelectedFiles(e.value); }, [setSelectedFiles]); const onAcceptChanged = useCallback((e: SelectBoxTypes.ValueChangedEvent) => { setAccept(e.value); }, [setAccept]); const onUploadModeChanged = useCallback((e: SelectBoxTypes.ValueChangedEvent) => { setUploadMode(e.value); }, [setUploadMode]); const onMultipleChanged = useCallback((e: CheckBoxTypes.ValueChangedEvent) => { setMultiple(e.value); }, [setMultiple]); return ( <div> <div className="widget-container"> <FileUploader multiple={multiple} accept={accept} uploadMode={uploadMode} uploadUrl="https://js.devexpress.com/Demos/NetCore/FileUploader/Upload" onValueChanged={onSelectedFilesChanged} /> <div className="content" style={{ display: selectedFiles.length > 0 ? 'block' : 'none' }}> <div> <h4>Selected Files</h4> {selectedFiles.map((file, i) => ( <div className="selected-item" key={i}> <span>{`Name: ${file.name}`}<br /></span> <span>{`Size ${file.size}`}<br /></span> <span>{`Type ${file.type}`}<br /></span> <span>{`Last Modified Date: ${file.lastModifiedDate}`}</span> </div> ))} </div> </div> </div> <div className="options"> <div className="caption">Options</div> <div className="option"> <span>File types</span> <SelectBox dataSource={fileTypesSource} inputAttr={fileTypeLabel} valueExpr="value" displayExpr="name" defaultValue="*" onValueChanged={onAcceptChanged} /> </div> <div className="option"> <span>Upload mode</span> <SelectBox items={uploadModes} defaultValue="instantly" inputAttr={uploadModeLabel} onValueChanged={onUploadModeChanged} /> </div> <div className="option"> <CheckBox text="Allow multiple files selection" onValueChanged={onMultipleChanged} /> </div> </div> </div> ); }
import React, { useCallback, useState } from 'react'; import FileUploader from 'devextreme-react/file-uploader'; import SelectBox from 'devextreme-react/select-box'; import CheckBox from 'devextreme-react/check-box'; const uploadModes = ['instantly', 'useButtons']; const fileTypeLabel = { 'aria-label': 'File Type' }; const uploadModeLabel = { 'aria-label': 'Mode' }; const fileTypesSource = [ { name: 'All types', value: '*' }, { name: 'Images', value: 'image/*' }, { name: 'Videos', value: 'video/*' }, ]; export default function App() { const [multiple, setMultiple] = useState(false); const [uploadMode, setUploadMode] = useState('instantly'); const [accept, setAccept] = useState('*'); const [selectedFiles, setSelectedFiles] = useState([]); const onSelectedFilesChanged = useCallback( (e) => { setSelectedFiles(e.value); }, [setSelectedFiles], ); const onAcceptChanged = useCallback( (e) => { setAccept(e.value); }, [setAccept], ); const onUploadModeChanged = useCallback( (e) => { setUploadMode(e.value); }, [setUploadMode], ); const onMultipleChanged = useCallback( (e) => { setMultiple(e.value); }, [setMultiple], ); return ( <div> <div className="widget-container"> <FileUploader multiple={multiple} accept={accept} uploadMode={uploadMode} uploadUrl="https://js.devexpress.com/Demos/NetCore/FileUploader/Upload" onValueChanged={onSelectedFilesChanged} /> <div className="content" style={{ display: selectedFiles.length > 0 ? 'block' : 'none' }} > <div> <h4>Selected Files</h4> {selectedFiles.map((file, i) => ( <div className="selected-item" key={i} > <span> {`Name: ${file.name}`} <br /> </span> <span> {`Size ${file.size}`} <br /> </span> <span> {`Type ${file.type}`} <br /> </span> <span>{`Last Modified Date: ${file.lastModifiedDate}`}</span> </div> ))} </div> </div> </div> <div className="options"> <div className="caption">Options</div> <div className="option"> <span>File types</span> <SelectBox dataSource={fileTypesSource} inputAttr={fileTypeLabel} valueExpr="value" displayExpr="name" defaultValue="*" onValueChanged={onAcceptChanged} /> </div> <div className="option"> <span>Upload mode</span> <SelectBox items={uploadModes} defaultValue="instantly" inputAttr={uploadModeLabel} onValueChanged={onUploadModeChanged} /> </div> <div className="option"> <CheckBox text="Allow multiple files selection" onValueChanged={onMultipleChanged} /> </div> </div> </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.4/cjs', 'devextreme-react': 'npm:devextreme-react@24.1.4/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.10/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.4/css/dx.light.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>
.widget-container { margin-right: 320px; } .content h4 { margin-bottom: 10px; font-weight: 500; font-size: 18px; } .content { margin-top: 50px; margin-left: 10px; display: none; } .selected-item { margin-bottom: 20px; } .options { padding: 20px; background-color: rgba(191, 191, 191, 0.15); position: absolute; right: 0; top: 0; bottom: 0; width: 260px; } .caption { font-size: 18px; font-weight: 500; } .option { margin-top: 10px; }

To select files, click the Select file button or drop the files directly on the component. If the upload mode is «useButtons», you must click the Upload button or a corresponding button for each file to initiate upload.

NOTE

This demo does not actually upload files. To upload files, assign the URL of a page providing server scenarios for saving uploaded files to the uploadUrl configuration property of the component.