Input Drag Drop
<section class="p-6 bg-white rounded-lg shadow-sm">
<div class="max-w-md mx-auto space-y-6">
<!-- Drag and Drop File Upload -->
<div class="space-y-2">
<label for="dropzone-file" class="block text-sm font-medium text-gray-700">Upload File</label>
<div class="flex items-center justify-center w-full">
<label for="dropzone-file" id="dropzone" class="flex flex-col items-center justify-center w-full h-64 border-2 border-gray-300 border-dashed rounded-lg cursor-pointer bg-gray-50 hover:bg-gray-100 transition-all duration-200">
<div class="flex flex-col items-center justify-center pt-5 pb-6">
<svg class="w-10 h-10 mb-3 text-gray-400" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M7 16a4 4 0 01-.88-7.903A5 5 0 1115.9 6L16 6a5 5 0 011 9.9M15 13l-3-3m0 0l-3 3m3-3v12"></path>
</svg>
<p class="mb-2 text-sm text-gray-500"><span class="font-semibold">Click to upload</span> or drag and drop</p>
<p class="text-xs text-gray-500">SVG, PNG, JPG or GIF (MAX. 5MB)</p>
</div>
<input id="dropzone-file" type="file" class="hidden" multiple />
</label>
</div>
<div id="file-list" class="mt-3 space-y-2"></div>
</div>
<!-- Drag and Drop Multiple Files with Preview -->
<div class="space-y-2">
<label for="dropzone-multiple" class="block text-sm font-medium text-gray-700">Upload Multiple Files</label>
<div class="flex items-center justify-center w-full">
<label for="dropzone-multiple" id="dropzone-multiple-container" class="flex flex-col items-center justify-center w-full h-64 border-2 border-gray-300 border-dashed rounded-lg cursor-pointer bg-gray-50 hover:bg-gray-100 transition-all duration-200">
<div class="flex flex-col items-center justify-center pt-5 pb-6">
<svg class="w-10 h-10 mb-3 text-gray-400" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 16v1a3 3 0 003 3h10a3 3 0 003-3v-1m-4-8l-4-4m0 0L8 8m4-4v12"></path>
</svg>
<p class="mb-2 text-sm text-gray-500"><span class="font-semibold">Click to upload multiple files</span> or drag and drop</p>
<p class="text-xs text-gray-500">PDF, DOC, XLS, TXT, or images (MAX. 10MB each)</p>
</div>
<input id="dropzone-multiple" type="file" class="hidden" multiple />
</label>
</div>
<div id="multiple-file-list" class="mt-3 space-y-2">
<p class="text-xs text-gray-500">No files selected</p>
</div>
</div>
</div>
<script>
// Single dropzone functionality
const dropzone = document.getElementById('dropzone');
const dropzoneInput = document.getElementById('dropzone-file');
const fileList = document.getElementById('file-list');
// Prevent default drag behaviors
['dragenter', 'dragover', 'dragleave', 'drop'].forEach(eventName => {
dropzone.addEventListener(eventName, preventDefaults, false);
document.body.addEventListener(eventName, preventDefaults, false);
});
// Highlight dropzone when item is dragged over it
['dragenter', 'dragover'].forEach(eventName => {
dropzone.addEventListener(eventName, highlight, false);
});
['dragleave', 'drop'].forEach(eventName => {
dropzone.addEventListener(eventName, unhighlight, false);
});
// Handle dropped files
dropzone.addEventListener('drop', handleDrop, false);
dropzoneInput.addEventListener('change', handleFiles, false);
function preventDefaults(e) {
e.preventDefault();
e.stopPropagation();
}
function highlight() {
dropzone.classList.add('border-blue-500', 'bg-blue-50');
dropzone.classList.remove('border-gray-300', 'bg-gray-50');
}
function unhighlight() {
dropzone.classList.remove('border-blue-500', 'bg-blue-50');
dropzone.classList.add('border-gray-300', 'bg-gray-50');
}
function handleDrop(e) {
const dt = e.dataTransfer;
const files = dt.files;
handleFiles({ target: { files } });
}
function handleFiles(e) {
const files = [...e.target.files];
fileList.innerHTML = '';
files.forEach(file => {
const fileSize = formatFileSize(file.size);
const fileItem = document.createElement('div');
fileItem.className = 'flex items-center justify-between p-2 bg-gray-50 rounded-md';
const fileInfo = document.createElement('div');
fileInfo.className = 'flex items-center space-x-2';
// Choose icon based on file type
let iconSvg = '';
if (file.type.startsWith('image/')) {
iconSvg = `<svg class="w-5 h-5 text-blue-500" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 16l4.586-4.586a2 2 0 012.828 0L16 16m-2-2l1.586-1.586a2 2 0 012.828 0L20 14m-6-6h.01M6 20h12a2 2 0 002-2V6a2 2 0 00-2-2H6a2 2 0 00-2 2v12a2 2 0 002 2z" />
</svg>`;
} else {
iconSvg = `<svg class="w-5 h-5 text-gray-500" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M7 21h10a2 2 0 002-2V9.414a1 1 0 00-.293-.707l-5.414-5.414A1 1 0 0012.586 3H7a2 2 0 00-2 2v14a2 2 0 002 2z" />
</svg>`;
}
fileInfo.innerHTML = `
${iconSvg}
<span class="text-sm font-medium text-gray-700 truncate max-w-xs">${file.name}</span>
`;
const fileMeta = document.createElement('div');
fileMeta.className = 'text-xs text-gray-500';
fileMeta.textContent = fileSize;
fileItem.appendChild(fileInfo);
fileItem.appendChild(fileMeta);
fileList.appendChild(fileItem);
});
}
// Multiple file dropzone
const dropzoneMultiple = document.getElementById('dropzone-multiple-container');
const dropzoneMultipleInput = document.getElementById('dropzone-multiple');
const multipleFileList = document.getElementById('multiple-file-list');
// Prevent default drag behaviors
['dragenter', 'dragover', 'dragleave', 'drop'].forEach(eventName => {
dropzoneMultiple.addEventListener(eventName, preventDefaultsMultiple, false);
});
// Highlight dropzone when item is dragged over it
['dragenter', 'dragover'].forEach(eventName => {
dropzoneMultiple.addEventListener(eventName, highlightMultiple, false);
});
['dragleave', 'drop'].forEach(eventName => {
dropzoneMultiple.addEventListener(eventName, unhighlightMultiple, false);
});
// Handle dropped files
dropzoneMultiple.addEventListener('drop', handleDropMultiple, false);
dropzoneMultipleInput.addEventListener('change', handleFilesMultiple, false);
function preventDefaultsMultiple(e) {
e.preventDefault();
e.stopPropagation();
}
function highlightMultiple() {
dropzoneMultiple.classList.add('border-blue-500', 'bg-blue-50');
dropzoneMultiple.classList.remove('border-gray-300', 'bg-gray-50');
}
function unhighlightMultiple() {
dropzoneMultiple.classList.remove('border-blue-500', 'bg-blue-50');
dropzoneMultiple.classList.add('border-gray-300', 'bg-gray-50');
}
function handleDropMultiple(e) {
const dt = e.dataTransfer;
const files = dt.files;
handleFilesMultiple({ target: { files } });
}
function handleFilesMultiple(e) {
const files = [...e.target.files];
multipleFileList.innerHTML = '';
if (files.length === 0) {
multipleFileList.innerHTML = '<p class="text-xs text-gray-500">No files selected</p>';
return;
}
files.forEach(file => {
const fileSize = formatFileSize(file.size);
const fileItem = document.createElement('div');
fileItem.className = 'flex items-center justify-between p-2 bg-gray-50 rounded-md';
const fileInfo = document.createElement('div');
fileInfo.className = 'flex items-center space-x-2';
// File type icon
let fileIcon = '';
if (file.type.startsWith('image/')) {
fileIcon = 'image';
} else if (file.type.includes('pdf')) {
fileIcon = 'pdf';
} else if (file.type.includes('word') || file.type.includes('doc')) {
fileIcon = 'doc';
} else if (file.type.includes('excel') || file.type.includes('sheet')) {
fileIcon = 'xls';
} else {
fileIcon = 'file';
}
// Icon SVG based on file type
let iconSvg = '';
switch(fileIcon) {
case 'image':
iconSvg = `<svg class="w-5 h-5 text-blue-500" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 16l4.586-4.586a2 2 0 012.828 0L16 16m-2-2l1.586-1.586a2 2 0 012.828 0L20 14m-6-6h.01M6 20h12a2 2 0 002-2V6a2 2 0 00-2-2H6a2 2 0 00-2 2v12a2 2 0 002 2z" />
</svg>`;
break;
case 'pdf':
iconSvg = `<svg class="w-5 h-5 text-red-500" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M7 21h10a2 2 0 002-2V9.414a1 1 0 00-.293-.707l-5.414-5.414A1 1 0 0012.586 3H7a2 2 0 00-2 2v14a2 2 0 002 2z" />
</svg>`;
break;
case 'doc':
iconSvg = `<svg class="w-5 h-5 text-blue-600" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z" />
</svg>`;
break;
case 'xls':
iconSvg = `<svg class="w-5 h-5 text-green-600" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 17v-2m3 2v-4m3 4v-6m2 10H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z" />
</svg>`;
break;
default:
iconSvg = `<svg class="w-5 h-5 text-gray-500" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M7 21h10a2 2 0 002-2V9.414a1 1 0 00-.293-.707l-5.414-5.414A1 1 0 0012.586 3H7a2 2 0 00-2 2v14a2 2 0 002 2z" />
</svg>`;
}
fileInfo.innerHTML = `
${iconSvg}
<span class="text-sm font-medium text-gray-700 truncate max-w-xs">${file.name}</span>
`;
const fileActions = document.createElement('div');
fileActions.className = 'flex items-center space-x-2';
const fileSizeSpan = document.createElement('span');
fileSizeSpan.className = 'text-xs text-gray-500';
fileSizeSpan.textContent = fileSize;
const removeButton = document.createElement('button');
removeButton.className = 'text-red-500 hover:text-red-700 focus:outline-none';
removeButton.innerHTML = `
<svg class="w-4 h-4" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12" />
</svg>
`;
fileActions.appendChild(fileSizeSpan);
fileActions.appendChild(removeButton);
fileItem.appendChild(fileInfo);
fileItem.appendChild(fileActions);
multipleFileList.appendChild(fileItem);
// Remove button functionality
removeButton.addEventListener('click', function() {
fileItem.remove();
if (multipleFileList.children.length === 0) {
multipleFileList.innerHTML = '<p class="text-xs text-gray-500">No files selected</p>';
}
});
});
}
// Helper function to format file size
function formatFileSize(bytes) {
if (bytes === 0) return '0 Bytes';
const k = 1024;
const sizes = ['Bytes', 'KB', 'MB', 'GB'];
const i = Math.floor(Math.log(bytes) / Math.log(k));
return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
}
</script>
</section>
Copied to clipboard