Multi file upload
- HTML (Multi file upload (example))
- Nunjucks (Multi file upload (example))
- JavaScript (Multi file upload (example))
- Figma
<div class="govuk-grid-row">
<div class="govuk-grid-column-two-thirds">
<h1 class="govuk-heading-xl">Upload files</h1>
<form action="/components/multi-file-upload/examples/default" method="post" enctype="multipart/form-data">
<div class="moj-multi-file-upload">
<div class="moj-multi-file__uploaded-files ">
<h2 class="govuk-heading-m">Files added</h2>
<div class="govuk-summary-list moj-multi-file-upload__list">
</div>
</div>
<div class="moj-multi-file-upload__upload">
<div class="govuk-form-group">
<label class="govuk-label govuk-label--m" for="documents">
Upload a file
</label>
<input class="govuk-file-upload moj-multi-file-upload__input" id="documents" name="documents" type="file" multiple="">
</div>
<button type="submit" class="govuk-button govuk-button--secondary moj-multi-file-upload__button" data-module="govuk-button">
Upload file
</button>
</div>
</div>
<button type="submit" class="govuk-button" data-module="govuk-button">
Continue
</button>
</form>
</div>
</div>
{%- from "govuk/components/file-upload/macro.njk" import govukFileUpload -%}
{%- from "govuk/components/button/macro.njk" import govukButton -%}
{%- from "govuk/components/error-summary/macro.njk" import govukErrorSummary -%}
{%- from "moj/components/multi-file-upload/macro.njk" import mojMultiFileUpload -%}
<div class="govuk-grid-row">
<div class="govuk-grid-column-two-thirds">
{% if errorSummary.items.length %}
{{ govukErrorSummary({
titleText: 'There is a problem',
errorList: errorSummary.items
}) }}
{% endif %}
<h1 class="govuk-heading-xl">Upload files</h1>
<form action="/components/multi-file-upload/examples/default" method="post" enctype="multipart/form-data">
{% set uploadHtml %}
{{ govukFileUpload({
id: "documents",
name: "documents",
classes: 'moj-multi-file-upload__input',
label: {
text: "Upload a file",
classes: 'govuk-label--m'
},
attributes: { multiple: '' },
errorMessage: errorMessage
}) }}
{{govukButton({
text: 'Upload file',
classes: 'govuk-button--secondary moj-multi-file-upload__button'
})}}
{% endset %}
{{ mojMultiFileUpload({
uploadedFiles: {
heading: { text: 'Files added' },
items: uploadedFiles
},
uploadHtml: uploadHtml
}) }}
{{govukButton({
text: 'Continue'
})}}
</form>
</div>
</div>
new MOJFrontend.MultiFileUpload({
container: document.querySelector(".moj-multi-file-upload"),
uploadUrl: "/ajax-upload",
deleteUrl: "/ajax-delete",
});
This component is in the ‘Assets’ tab in the MoJ Figma Kit.
If you’re external to MoJ, download the Kit and add it as a library to your Figma files. You’ll need to re-add the kit to update the version.
When to use
Use the multi file upload component to help users upload multiple files at the same time, on a regular basis. For example, in a caseworking system.
When not to use
Do not use this component if users only need to upload one file.
Uploading multiple files at the same time is more error prone than uploading files, one at a time. This is because users have to use a custom form control that may not be as easy to understand.
For this reason, do not use this component unless research shows that users need a faster way to upload files.
How to use
The multi file upload consists of a dropzone and feedback area which starts off hidden.
Users can drag and drop files onto the dropzone or click the button and select files using the file picker.
Each selected file will start uploading immediately and appear as a row in the feedback area. Each file’s progress is indicated as a percentage.
When a file has been uploaded it will show as:
- green, next to a tick icon, if it’s been uploaded successfully
- red, next to a warning icon, if there’s been an error
Initialising the JavaScript
The multi file upload component uses JavaScript. To run it you must include the following script in your page:
if(typeof MOJFrontend.MultiFileUpload !== 'undefined') {
new MOJFrontend.MultiFileUpload({
container: document.querySelector('.moj-multi-file-upload'),
uploadUrl: '/ajax-upload-url',
deleteUrl: '/ajax-delete-url'
});
}
When JavaScript is not available
When JavaScript is not available, users will be presented with a file upload component and upload button.
When the user selects the upload button, the page will refresh with the valid files being shown in the feedback area.
- HTML (Multi file upload without JavaScript (example))
- Nunjucks (Multi file upload without JavaScript (example))
<div class="govuk-grid-row">
<div class="govuk-grid-column-two-thirds">
<h1 class="govuk-heading-xl">Upload files</h1>
<form action="" method="post" enctype="multipart/form-data">
<div class="moj-multi-file-upload">
<div class="moj-multi-file__uploaded-files moj-hidden">
<h2 class="govuk-heading-m">Files added</h2>
<div class="govuk-summary-list moj-multi-file-upload__list">
</div>
</div>
<div class="moj-multi-file-upload__upload">
<div class="govuk-form-group">
<label class="govuk-label govuk-label--m" for="documents">
Upload a file
</label>
<input class="govuk-file-upload moj-multi-file-upload__input" id="documents" name="documents" type="file" multiple="">
</div>
<button type="submit" class="govuk-button govuk-button--secondary moj-multi-file-upload__button" data-module="govuk-button">
Upload file
</button>
</div>
</div>
<button type="submit" class="govuk-button" data-module="govuk-button">
Continue
</button>
</form>
</div>
</div>
{%- from "govuk/components/file-upload/macro.njk" import govukFileUpload -%}
{%- from "govuk/components/button/macro.njk" import govukButton -%}
{%- from "govuk/components/error-summary/macro.njk" import govukErrorSummary -%}
{%- from "moj/components/multi-file-upload/macro.njk" import mojMultiFileUpload -%}
<div class="govuk-grid-row">
<div class="govuk-grid-column-two-thirds">
<h1 class="govuk-heading-xl">Upload files</h1>
<form action="" method="post" enctype="multipart/form-data">
{% set uploadHtml %}
{{ govukFileUpload({
id: "documents",
name: "documents",
classes: 'moj-multi-file-upload__input',
label: {
text: "Upload a file",
classes: 'govuk-label--m'
},
attributes: { multiple: '' }
}) }}
{{govukButton({
text: 'Upload file',
classes: 'govuk-button--secondary moj-multi-file-upload__button'
})}}
{% endset %}
{{ mojMultiFileUpload({
uploadedFiles: {
heading: { text: 'Files added' },
items: []
},
uploadHtml: uploadHtml
}) }}
{{govukButton({
text: 'Continue'
})}}
</form>
</div>
</div>
When there are multiple files with errors, you must put:
- separate error messages in the error summary from the GOV.UK Design System — each one must link to the multi file upload
- all error messages next to the field separated by a line break (
<br>
)
- HTML (Multi file upload without JavaScript with errors (example))
- Nunjucks (Multi file upload without JavaScript with errors (example))
<div class="govuk-grid-row">
<div class="govuk-grid-column-two-thirds">
<div class="govuk-error-summary" aria-labelledby="error-summary-title" role="alert" tabindex="-1">
<h2 class="govuk-error-summary__title" id="error-summary-title">
There is a problem
</h2>
<div class="govuk-error-summary__body">
<ul class="govuk-list govuk-error-summary__list">
<li>
<a href="#documents">name-of-file-1.pdf must be a png or gif</a>
</li>
<li>
<a href="#documents">name-of-file-2.pdf must be a png or gif</a>
</li>
</ul>
</div>
</div>
<h1 class="govuk-heading-xl">Upload files</h1>
<form action="" method="post" enctype="multipart/form-data">
<div class="moj-multi-file-upload">
<div class="moj-multi-file__uploaded-files moj-hidden">
<h2 class="govuk-heading-m">Files added</h2>
<div class="govuk-summary-list moj-multi-file-upload__list">
</div>
</div>
<div class="moj-multi-file-upload__upload">
<div class="govuk-form-group govuk-form-group--error">
<label class="govuk-label govuk-label--m" for="documents">
Upload a file
</label>
<p id="documents-error" class="govuk-error-message">
<span class="govuk-visually-hidden">Error:</span> name-of-file-1.pdf must be a png or gif<br>name-of-file-2.pdf must be a png or gif
</p>
<input class="govuk-file-upload moj-multi-file-upload__input govuk-file-upload--error" id="documents" name="documents" type="file" aria-describedby="documents-error" multiple="">
</div>
<button type="submit" class="govuk-button govuk-button--secondary moj-multi-file-upload__button" data-module="govuk-button">
Upload file
</button>
</div>
</div>
<button type="submit" class="govuk-button" data-module="govuk-button">
Continue
</button>
</form>
</div>
</div>
{%- from "govuk/components/file-upload/macro.njk" import govukFileUpload -%}
{%- from "govuk/components/button/macro.njk" import govukButton -%}
{%- from "govuk/components/error-summary/macro.njk" import govukErrorSummary -%}
{%- from "moj/components/multi-file-upload/macro.njk" import mojMultiFileUpload -%}
<div class="govuk-grid-row">
<div class="govuk-grid-column-two-thirds">
<div class="govuk-error-summary" aria-labelledby="error-summary-title" role="alert" tabindex="-1">
<h2 class="govuk-error-summary__title" id="error-summary-title">
There is a problem
</h2>
<div class="govuk-error-summary__body">
<ul class="govuk-list govuk-error-summary__list">
<li>
<a href="#documents">name-of-file-1.pdf must be a png or gif</a>
</li>
<li>
<a href="#documents">name-of-file-2.pdf must be a png or gif</a>
</li>
</ul>
</div>
</div>
<h1 class="govuk-heading-xl">Upload files</h1>
<form action="" method="post" enctype="multipart/form-data">
{% set uploadHtml %}
{{ govukFileUpload({
id: "documents",
name: "documents",
classes: 'moj-multi-file-upload__input',
label: {
text: "Upload a file",
classes: 'govuk-label--m'
},
attributes: { multiple: '' },
errorMessage: {
html: 'name-of-file-1.pdf must be a png or gif<br>name-of-file-2.pdf must be a png or gif'
}
}) }}
{{govukButton({
text: 'Upload file',
classes: 'govuk-button--secondary moj-multi-file-upload__button'
})}}
{% endset %}
{{ mojMultiFileUpload({
uploadedFiles: {
heading: { text: 'Files added' },
items: []
},
uploadHtml: uploadHtml
}) }}
{{govukButton({
text: 'Continue'
})}}
</form>
</div>
</div>
If the form contains other questions and the user selects the upload button:
- save their answers and present them back
- if there are errors, show them in the error summary and next to the related fields
When the user selects the continue button, the entire form including selected files, will be saved and the user will be taken to the next page.
You can include a check screen at this point if you need to.
Error messages
Use the file upload error messages from the GOV.UK Design System.
Get help and contribute
Get help
You can contact the MoJ Design System team for help or support using this component.
Help improve this component
The MoJ Design System team would like to hear:
- how you have used this component in your service
- any feedback you have about its usage, for example accessibility or ideas for improvement
Add these comments to the multi file upload discussion on Github.