This implementation extends the existing document upload functionality to support multiple document uploads within a single widget, similar to the IR (Image Recognition) components. The new system allows users to upload multiple documents, images, and camera captures in the same widget while maintaining backward compatibility with existing code.
- Upload multiple documents in a single widget
- Support for documents (PDF, DOC, DOCX) and images (JPG, PNG, HEIC, HEIF)
- Camera capture functionality
- Gallery selection
- Configurable maximum file limits
- Horizontal scrolling list of uploaded documents
- Individual file preview with icons
- Remove functionality for each file
- File count indicators
- Modern modal bottom sheet picker
- Before: Single
blobKeystring - After: Array of
blobKeystrings (List<String>) - Backward compatibility maintained via
DocumentUploadSingle
- New:
UploadedDocumentmodel class - Modified:
DocumentUploadwidget to handle multiple files - Added:
DocumentUploadSinglefor backward compatibility
- Updated: To work with new multiple document structure
- Changed: From single
blobKeytoList<String> blobKeys - Enhanced: Better handling of document types
- Added:
updateMultipleDocumentField()method - Added:
updateOutletMappingDetailsWithArray()method - Enhanced: Support for array storage in
extendedAttributes
- Created: Usage examples and integration guide
DocumentUpload(
fieldDetails: FormFields(
widgetId: 'documents',
label: 'Upload Documents',
enabled: true,
extAttrKey: 'documents',
type: 'document',
),
widgetId: 'documents',
maxFiles: 5, // Allow up to 5 files
allowMultiple: true,
onFilesSelected: (blobKeys) {
// Handle array of blobKeys
print('Uploaded documents: $blobKeys');
// Store in outlet payload as array
outletPayload.extendedAttributes['documents'] = blobKeys;
},
)// In OutletMappingDocument widget
DocumentUpload(
fieldDetails: widget.fieldDetails,
existingBlobKeys: currentBlobKeys, // List<String>
widgetId: widget.fieldDetails.widgetId,
maxFiles: 5,
allowMultiple: true,
onFilesSelected: (blobKeys) {
// Update outlet payload with array
outletMappingProvider.outletPayload.extendedAttributes[widgetId] = blobKeys;
outletMappingProvider.notifyListeners();
},
)// For existing code that expects single blobKey
DocumentUploadSingle(
fieldDetails: fieldDetails,
existingBlobKey: singleBlobKey, // String?
onFileSelected: (blobKey) {
// Handle single blobKey as before
print('Single document: $blobKey');
},
)User taps upload area
↓
Modal bottom sheet shows options
↓
User selects Camera/Gallery/Documents
↓
Files are processed and uploaded
↓
BlobKeys are generated
↓
UploadedDocument objects created
↓
UI updates with file previews
↓
Parent callback fired with blobKey array
// Regular documents (DNI, CUITCertificate, etc.)
outletPayload.extendedAttributes['DNI'] = ['blobKey1', 'blobKey2', 'blobKey3'];
// Additional documents (contractRental, propertyTax, etc.)
outletPayload.extendedAttributes['additionaldocumentation'] = {
'contractRental': ['blobKey1', 'blobKey2'],
'propertyTax': ['blobKey3'],
'utilityBill': ['blobKey4', 'blobKey5']
};| Parameter | Type | Default | Description |
|---|---|---|---|
maxFiles |
int |
10 |
Maximum number of files allowed |
allowMultiple |
bool |
true |
Whether multiple files are allowed |
existingBlobKeys |
List<String>? |
null |
Previously uploaded blobKeys |
onFilesSelected |
Function(List<String>) |
- | Callback with selected blobKeys |
dontProvideGallery |
bool |
false |
Hide gallery option |
- Documents: PDF, DOC, DOCX
- Images: JPG, JPEG, PNG, HEIC, HEIF
- Camera: Direct photo capture
- Option 1: Use
DocumentUploadSingle(no changes required) - Option 2: Migrate to new
DocumentUploadwith array handling
// Before
DocumentUpload(
existingBlobKey: singleBlobKey, // String?
onFileSelected: (blobKey) { ... }, // Single value
)
// After - Option 1 (Backward Compatible)
DocumentUploadSingle(
existingBlobKey: singleBlobKey, // String?
onFileSelected: (blobKey) { ... }, // Single value
)
// After - Option 2 (New Multiple Support)
DocumentUpload(
existingBlobKeys: blobKeys, // List<String>?
onFilesSelected: (blobKeys) { ... }, // Array value
maxFiles: 5, // Configure limit
)// Before
outletPayload.extendedAttributes['document'] = 'single_blob_key';
// After
outletPayload.extendedAttributes['document'] = ['blob_key_1', 'blob_key_2'];
// Access first document (backward compatibility)
String? firstDoc = (outletPayload.extendedAttributes['document'] as List?)?.first;class UploadedDocument {
final String id; // Unique identifier
final String name; // File name
final String path; // Local file path
final String extension; // File extension
final String blobKey; // Server blob key
final DateTime uploadTime; // Upload timestamp
final String type; // 'image' or 'document'
}- Upload Trigger: Main upload area with file count indicator
- Document List: Horizontal scrollable list of uploaded files
- Document Cards: Individual file previews with remove buttons
- Modal Picker: Bottom sheet with camera/gallery/document options
- File validation for supported formats
- Size limit checks
- Upload failure handling
- Network timeout handling
- Visual error feedback to users
-
Multiple Document Upload
- Upload multiple PDF files
- Upload mixed file types (PDF + images)
- Verify file count limits
- Test remove functionality
-
Camera Integration
- Capture photos from camera
- Mix camera photos with documents
- Verify image processing
-
Backward Compatibility
- Test
DocumentUploadSinglewith existing code - Verify single file limitation
- Ensure callback compatibility
- Test
-
Edge Cases
- Network failures during upload
- Large file uploads
- Maximum file limit reached
- Empty state handling
- Upload multiple documents at once
- Visual feedback for each file
- Easy file management with remove options
- Familiar UI patterns from IR components
- Clean API design
- Backward compatibility
- Comprehensive error handling
- Flexible configuration options
- Structured storage in arrays
- Easy iteration over multiple files
- Simplified server-side processing
- Better data organization
- File Preview: Image thumbnails and document previews
- Drag & Drop: Desktop/web drag and drop support
- Progress Indicators: Upload progress for large files
- Cloud Integration: Direct cloud storage uploads
- File Compression: Automatic image/document compression
- Batch Operations: Select/deselect all functionality
- Files not appearing: Check
maxFileslimit andallowMultiplesetting - Callback not firing: Ensure
onFilesSelectedis properly set - UI not updating: Verify
setState()is called in callback - Storage issues: Check
extendedAttributesstructure in outlet payload
- Enable logging to see blobKey arrays
- Use Flutter Inspector to verify widget tree
- Check network requests for upload failures
- Validate file permissions on device
This implementation provides a robust, scalable solution for multiple document uploads while maintaining compatibility with existing systems.