Last active
March 11, 2025 17:43
-
-
Save ajmas/5710ac15c48b74b806bee9c2073b44dc to your computer and use it in GitHub Desktop.
Revisions
-
ajmas revised this gist
Mar 11, 2025 . 2 changed files with 32 additions and 0 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,13 @@ .dropzone.dropzone-active { box-shadow: 0px 0px 15px 0px rgba(73, 245, 54, 0.75); } .dropzone.dropzone-badtype { cursor: no-drop; box-shadow: 0px 0px 15px 0px rgba(248, 19, 19, 0.75); content: url("./white-x-icon.svg"); } #error_message { color: red; } LoadingSorry, something went wrong. Reload?Sorry, we cannot display this file.Sorry, this file is invalid so it cannot be displayed. -
ajmas revised this gist
Mar 11, 2025 . 1 changed file with 3 additions and 1 deletion.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1,5 +1,7 @@ /** This is a rudementary implementation to allow drag an drop upload on an HTML page. It was made for a project I was working on, but thought I'd share it for anyone interested and for eventual feedback. - Supports limiting: - file type -
ajmas created this gist
Mar 11, 2025 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,137 @@ /** This is a rudementary implementation to allow drag an drop upload on an HTML page. - Supports limiting: - file type - file size - number of files uploaded - Disables dropping files elsewhere on the page - What you need to provide: - an element to act as drop zone and adjust vlaue of `dropZoneSelector` - file input element and ajdust the value of `fileInputSelector` - error element and adjust the value of `errorSelector` Note, due to browser security model, we can't get the file size during dragging. It is only available once the files are dropped. */ const supportedFileTypes = ['image/jpeg', 'image/png', 'video/mp4', 'application/zip']; const maxFileCount = 7; const maxFileSizeMB = 24; const dropZoneSelector = '.dropzone'; const fileInputSelector = '#id_file'; const errorSelector = '#error_message'; function toBytes (sizeInMegaBytes) { return sizeInMegaBytes * 1024 * 1024; } function onDragZoneChange () { document.querySelector(dropZoneSelector).classList.remove('dropzone-active'); document.querySelector(dropZoneSelector).classList.remove('dropzone-badtype'); } function isValidFileItem (fileItem) { return !!(supportedFileTypes.indexOf(fileItem.type) > -1); } function onFileDrop (event) { event.preventDefault(); onDragZoneChange(); const errorOutput = document.querySelector(errorSelector); if (errorOutput) { errorOutput.innerHTML = ' '; } const maxFileSize = toBytes(maxFileSizeMB); let dataTransfer = new DataTransfer(); let tooBig = false; let tooManyFiles = false; if (event.dataTransfer.files) { [...event.dataTransfer.files].forEach((file) => { if (file.size > maxFileSize) { tooBig = true; return; } else if (dataTransfer.items.length > maxFileCount) { tooManyFiles = true; return; } if (isValidFileItem(file) && dataTransfer.items.length < maxFileCount) { dataTransfer.items.add(file); } }); } const fileInput = document.querySelector(fileInputSelector); fileInput.files = dataTransfer.files; fileInput.dispatchEvent(new Event('change', { bubbles: true })); if (errorSelector) { const messages = []; if (tooBig) { messages.push(`Files larger than ${maxFileSizeMB} MB were ignored`); } if (tooManyFiles) { messages.push(`Uploads are limited to ${maxFileCount} files per submission`); } errorOutput.innerHTML = messages.join('; '); } } function onDragOver (event) { event.preventDefault(); event.stopPropagation(); document.querySelector(dropZoneSelector).classList.add('dropzone-active'); let permitted = true; if (event.dataTransfer.items) { [...event.dataTransfer.items].forEach((item) => { if (!isValidFileItem(item)) { permitted = false; } }); } else { [...event.dataTransfer.files].forEach((file) => { if (!isValidFileItem(item)) { permitted = false; } }); } if (!permitted) { document.querySelector(dropZoneSelector).classList.add('dropzone-badtype'); event.dataTransfer.dropEffect = 'none'; event.dataTransfer.effectAllowed = 'none'; } } document.addEventListener('DOMContentLoaded', () => { const dropZone = document.querySelector(dropZoneSelector); if (dropZone) { dropZone.addEventListener('drop', onFileDrop); dropZone.addEventListener('dragenter', onDragOver); dropZone.addEventListener('dragover', onDragOver); dropZone.addEventListener('dragleave', onDragZoneChange); } // logic to prevent items being dropped elsewhere in the page const body = document.querySelector('body'); body.addEventListener('dragover', (event) => { event.preventDefault(); event.stopPropagation(); event.dataTransfer.dropEffect = 'none'; event.dataTransfer.effectAllowed = 'none'; }); })