Skip to content

Commit

Permalink
[#1979] Added error validation for document-upload
Browse files Browse the repository at this point in the history
  • Loading branch information
jiromaykin committed Feb 6, 2024
1 parent a5f2d32 commit 9bbae9c
Show file tree
Hide file tree
Showing 3 changed files with 73 additions and 44 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<div class="form__control file-input" aria-live="polite">
{% render_card direction="vertical" %}
{% icon icon="upload" icon_position="before" outlined=True %}
<input class="file-input__input" id="{{ field.auto_id }}" name="file" type="file"{% if field.field.required %} required{% endif %}{% if multiple %} multiple{% endif %} data-max-size="{{ openzaak_config.max_upload_size }}">
<input class="file-input__input" id="{{ field.auto_id }}" name="file" type="file"{% if field.field.required %} required{% endif %}{% if multiple %} multiple{% endif %} data-max-size="{{ openzaak_config.max_upload_size }}" data-file-types="{{ openzaak_config.allowed_file_extensions }}">
<label class="button button--primary file-input__label-empty" for="{{ field.auto_id }}">
{% if multiple %}{% trans 'Sleep of selecteer bestanden' %}{% else %}{% trans 'Sleep of selecteer bestand' %}{% endif %}
</label>
Expand Down
112 changes: 71 additions & 41 deletions src/open_inwoner/js/components/form/FileInput.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,14 @@ export class FileInput extends Component {
return parseInt(this.getInput().dataset.maxSize)
}

/**
* Get configured limited file-types from 'data-file-types', return as clean string, and use in node.
* @returns {string} of file extensions.
*/
getUploadTypes() {
return this.getInput().dataset.fileTypes.replace(/["|'\[\]]/g, '')
}

/**
* Returns the card (drop zone) associated with the file input.
* @return {HTMLDivElement}
Expand Down Expand Up @@ -156,33 +164,39 @@ export class FileInput extends Component {
}

/**
* Gets called when click event is received on the files list, it originates from a delete button, handle the deletion accordingly.
* Gets called when click event is received on the files list, it originates from a delete button, to handle the deletion accordingly.
* @param {PointerEvent} e
*/
onClick(e) {
e.preventDefault()
const { target } = e

// Do nothing if the click does not originate from a delete button.
if (
!target.classList.contains('link') &&
!target.parentElement.classList.contains('link')
) {
return
}
// Check if the click originates from a delete button
const isDeleteButton =
// Filter the file list.
target.classList.contains('link') ||
target.parentElement.classList.contains('link')

// Filter the file list.
const listItem = target.closest('.file-list__list-item')
const index = [...this.getFilesList().children].indexOf(listItem)
const input = this.getInput()
if (isDeleteButton) {
const listItem = target.closest('.file-list__list-item')

const files = [...input.files].filter((_, i) => i !== index)
// Ensure the list item is found
if (listItem) {
const index = Array.from(listItem.parentElement.children).indexOf(
listItem
)
const input = this.getInput()

this.addFiles(files, true)
this.files = files
// Use filter, not splice
const files = Array.from(input.files).filter((_, i) => i !== index)

// We need to render manually since we're not making state changes.
this.render()
this.addFiles(files, true)
this.files = files

// We need to render manually since we're not making state changes.
this.render()
}
}
}

/**
Expand Down Expand Up @@ -271,39 +285,55 @@ export class FileInput extends Component {

// Only show errors notification if data-max-file-size is exceeded + add error class to file-list
const maxMegabytes = this.getLimit()
const uploadFileTypes = this.getUploadTypes().toUpperCase()

const sizeError = sizeMB > maxMegabytes
// Show fil-type error if allowed types DO contain the extension and returns true
const typeError = !uploadFileTypes.includes(ext)

const htmlStart = `
<li class="file-list__list-item">
<aside class="file">
<div class="file__container">
${
sizeMB > maxMegabytes
? '<div class="file__file error">'
: '<div class="file__file">'
}
<p class="file__symbol">
<span aria-hidden="true" class="material-icons-outlined">${
type.match('image') ? 'image' : 'description'
}</span>
</p>
<p class="p file__data">
<span class="file__name">${name} (${ext}, ${sizeMB}MB)</span>
</p>
<a class="link link--primary" href="#" role="button" aria-label="${labelDelete}">
<span aria-hidden="true" class="material-icons-outlined">delete</span>
</a>
</div>
<li class="file-list__list-item">
<aside class="file">
<div class="file__container">
<div class="file__file ${sizeError ? 'error' : ''} ${
typeError ? 'error' : ''
}">
<p class="file__symbol">
<span aria-hidden="true" class="material-icons-outlined">${
type.match('image') ? 'image' : 'description'
}</span>
</p>
<p class="p file__data">
<span class="file__name">${name} (${ext}, ${sizeMB}MB)</span>
</p>
<a class="link link--primary" href="#document-upload" role="button" aria-label="${labelDelete}">
<span aria-hidden="true" class="material-icons-outlined">delete</span>
</a>
</div>
</aside>
</li>`
</div>
</aside>
</li>`

if (sizeMB > maxMegabytes) {
// If uploaded field does NOT contain allowed extension
if (typeError) {
getFormNonFieldError.removeAttribute('hidden')
formSubmitButton.setAttribute('disabled', 'true')

return (
htmlStart +
`<p class="p p--small error">
<span aria-hidden="true" class="material-icons-outlined">warning_amber</span>
Dit type bestand (${ext}) is ongeldig. Geldige bestandstypen zijn: ${uploadFileTypes}.
</p>`
)
}
if (sizeError) {
getFormNonFieldError.removeAttribute('hidden')
formSubmitButton.setAttribute('disabled', 'true')

return (
htmlStart +
`<p class="p p--small p--centered error">
`<p class="p p--small error">
<span aria-hidden="true" class="material-icons-outlined">warning_amber</span>
Dit bestand is te groot
</p>`
Expand Down
3 changes: 1 addition & 2 deletions src/open_inwoner/scss/components/Form/FileInput.scss
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@
}
}

.p--centered.error {
.error {
color: var(--color-red-notification);
display: flex;
align-items: normal;
Expand All @@ -109,7 +109,6 @@

[class*='icon'] {
color: var(--color-red-notification);
font-size: var(--font-size-body-large);
}
}
}
Expand Down

0 comments on commit 9bbae9c

Please sign in to comment.