File Upload
Enhance the existing .file-field with a FilePond drag-and-drop uploader.
Basic example
Choose or drop an image to preview it with FilePond. This demonstration keeps files local to the page.
<div class="file-field input-field" data-file-picker="filepond" data-file-plugins="image-preview,file-validate-type">
<div class="btn">
<span>File</span>
<input type="file" accept="image/*">
</div>
<div class="file-path-wrapper">
<input class="file-path validate" type="text" placeholder="Upload one or more files">
</div>
</div>Setup
Start with the kmaterialize CSS and JavaScript from Getting started, then follow the component setup below.
FileInput enhances the existing .file-field structure in
place with a FilePond drag-and-drop uploader - add
data-file-picker="filepond" to an otherwise completely stock
.file-field, nothing else about the markup changes. FilePond hides the native
<input type="file"> and injects its own root as a sibling, so the surrounding
button/label/file-path-wrapper stay intact at rest.
FilePond is an optional peer dependency, loaded on demand - install it yourself
(npm install filepond) and import its base stylesheet once. The image-preview
plugin also requires its own stylesheet. Optional plugins
(image-preview, file-validate-type,
image-exif-orientation) are each their own optional peer, listed via
data-file-plugins="image-preview,file-validate-type".
import 'filepond/dist/filepond.min.css';
import 'filepond-plugin-image-preview/dist/filepond-plugin-image-preview.min.css';
Load the peer styles before kmaterialize/dist/css/materialize.css so the Material theme takes precedence.
this.el is the .file-field container itself, not the file input.
document.addEventListener('DOMContentLoaded', function() {
const elems = document.querySelectorAll('.file-field[data-file-picker="filepond"]');
const instances = FileInput.init(elems, {
// specify options here
});
});
Examples and variants
These examples use FilePond's native options through attributes on the file input. No upload endpoint is configured, so files stay local to this page.
Basic file
<div class="file-field input-field" data-file-picker="filepond">
<label for="file-basic">Attachment</label>
<div class="btn"><span>File</span>
<input id="file-basic" type="file"
data-label-idle='Drop a file or <span class="filepond--label-action">browse</span>'>
</div>
<div class="file-path-wrapper">
<input class="file-path validate" type="text" placeholder="Choose a file">
</div>
</div>Multiple images, sortable, maximum 3
<label for="file-multiple">Gallery images</label>
<input id="file-multiple" type="file" accept="image/*" multiple
data-max-files="3" data-allow-reorder="true">PNG, JPEG or GIF only
<label for="file-image-types">Image</label>
<input id="file-image-types" type="file"
accept="image/png,image/jpeg,image/gif"
data-drop-validation="true">Custom drop label
<label for="file-document">Document</label>
<input id="file-document" type="file"
data-label-idle='Drop a document here or <span class="filepond--label-action">browse</span>'
data-instant-upload="false">Compact image preview
<label for="file-compact">Profile photo</label>
<input id="file-compact" type="file" accept="image/*"
data-style-panel-layout="compact" data-file-height="76">Disabled
<label for="file-disabled">Attachment</label>
<input id="file-disabled" type="file" disabled>Default file
<label for="file-default">Profile image</label>
<input id="file-default" type="file" accept="image/*"
data-default-file="/images/sample-1.jpg">Value set programmatically
const field = document.querySelector('#file-value-field');
const instance = FileInput.getInstance(field);
await instance.ready;
await instance.pond.addFile('https://fastly.picsum.photos/id/265/200/300.jpg?hmac=NX0ut-ylHFyYKa4TxhZFNElh-h6RcVV7P4PNPgeBxKk');Labels and placeholder icons
Icon before
<label for="file-icon-before">Contract</label>
<input id="file-icon-before" type="file"
data-label-idle='<span class="filepond-label-content"><i class="material-icons">upload_file</i><span>Drop or <span class="filepond--label-action">browse</span></span></span>'>Icon after
<label for="file-icon-after">Attachment</label>
<input id="file-icon-after" type="file"
data-label-idle='<span class="filepond-label-content"><span>Drop or <span class="filepond--label-action">browse</span></span><i class="material-icons">attach_file</i></span>'>Validation
Use required on the file input. accept filters the chooser but does not validate uploaded content. Validate file type and size in your application and on the server; display those errors beside the upload field.
These previews keep their error state visible. In your form, show errors after checking a field or submitting, then clear them when the value is valid.
For text fields, use .input-field.error, aria-invalid="true", and a message linked with aria-describedby. Remove the error state when resolved. Use aria-live="polite" for messages updated dynamically.
Required attachment
<div class="file-field input-field error">
<div class="btn tonal">
<span>Choose PDF</span>
<input id="validation-file" type="file" accept="application/pdf" required aria-label="PDF attachment" aria-invalid="true" aria-describedby="validation-file-error">
</div>
<div class="file-path-wrapper">
<input class="file-path" type="text" placeholder="Attach a PDF" aria-label="Selected filename" readonly>
</div>
<span id="validation-file-error" class="supporting-text"><i class="material-icons" aria-hidden="true">error</i> Attach a PDF file before continuing.</span>
</div>Reference
Options
| Name | Type | Default | Description |
|---|---|---|---|
| plugins | Array | [] |
Which FilePond plugins to register: any of 'image-preview',
'file-validate-type', 'image-exif-orientation'. Derived
from data-file-plugins if not passed. file-validate-type
is auto-registered whenever the input restricts accept, even if not listed.
|
| Input attributes | HTML attributes | - |
Supports multiple, accept,
disabled, data-default-file,
data-max-files,
data-allow-reorder, data-label-idle,
data-instant-upload, data-drop-validation,
data-image-preview-height,
data-style-panel-layout, and
data-style-panel-aspect-ratio. Use
data-file-height to give compact layouts an explicit pixel height.
|
Methods
All the methods are called on the plugin instance. You can get the plugin instance like this:
const instance = FileInput.getInstance(elem);
.getFiles();
Convenience wrapper over the underlying FilePond instance's own getFiles().
Return Value
Array: The FilePond file items currently loaded.
instance.getFiles();
.destroy();
Destroy plugin instance and teardown the FilePond widget.
instance.destroy();
Properties
| Name | Type | Description |
|---|---|---|
| el | Element | The .file-field container the plugin was initialized with. |
| ready | Promise<void> | Resolves once FilePond (and its plugins) have loaded and the widget has been created. |
| pond | FilePond | The underlying FilePond instance, once ready resolves. |