Documentation Index
Fetch the complete documentation index at: https://docs.joyfill.io/llms.txt
Use this file to discover all available pages before exploring further.
This document provides comprehensive information about all available events in JoyDoc and how to handle them.
Event Overview Table
| Event Name | Event Triggers | Purpose |
|---|
onFocus | When a field receives focus | Track field focus events for analytics, validation, or UI updates |
onChange | When document data changes (field changes, field position changes, page changes, style changes, theme changes) | Handle document updates, save changes, or sync with external systems |
onBlur | When a field loses focus | Track field blur events for validation or cleanup operations |
onUploadAsync | When images or files are uploaded | Handle file uploads to external storage or processing services |
onCaptureAsync | When barcode is captured for table barcode cells | Handle camera capture functionality for barcode fields |
onFileUploadAsync | When images or files are uploaded | Handle field-specific file uploads with custom logic |
onFileClick | When a file in a field is clicked | Handle file interactions like opening, previewing, or downloading |
onFileDelete | When a file in a field is deleted | Handle file deletion with cleanup or confirmation logic |
onError | When errors occur (schema validation, license, etc.) | Handle and display errors to users |
Event Details
onFocus
- Triggered when: A field receives focus
- Purpose: Track field focus events for analytics, validation, or UI updates
Event signature:
onFocus(params, e) => {
// params contains field and document information
// e is the native focus event
}
Parameters:
params: Object containing:
sdk: ‘js’
v: 1
type: ‘fieldPositionFocus’
_id: Document ID
identifier: Document identifier
fileId: File ID
pageId: Page ID
fieldId: Field ID
fieldIdentifier: Field identifier
fieldPositionId: Field position ID
fieldRowId: Row ID (for table fields)
fieldColumnId: Column ID (for table fields)
fieldColumnIdentifier: Column identifier (for table fields)
e: Native DOM focus event
Example:
<JoyDoc
onFocus={(params, e) => {
console.log('Field focused:', params.fieldId);
// Call e.blur() to blur the field programmatically
setTimeout(() => e.blur(), 3000);
}}
/>
onChange
- Triggered when: Document data changes
- Purpose: Handle document updates, save changes, or sync with external systems
Triggered for:
- Field changes - Field value or property updates
- Field position changes - Field position, size, or display changes
- Page changes - Page creation, updates, or deletion
- Style changes - Theme and styling modifications
- Theme changes - Toggle between themes
All these will cause changes to the document data
Event signature:
onChange(changelog, doc) => {
// changelog contains the changes made
// doc contains the updated document
}
Parameters:
changelog: Array of change objects describing what was modified
doc: The updated document object
Example:
<JoyDoc
onChange={(changelog, doc) => {
console.log('Document changed:', changelog);
console.log('Updated document:', doc);
// Save changes to server
saveDocument(doc);
// Update local state
setDocument(doc);
}}
/>
onBlur
- Triggered when: A field loses focus
- Purpose: Track field blur events for validation or cleanup operations
Event signature:
onBlur(params, e) => {
// params contains field and document information
// e is the native blur event
}
Parameters:
params: Object containing:
sdk: ‘js’
v: 1
target: ‘fieldPositionBlur’
_id: Document ID
identifier: Document identifier
fileId: File ID
pageId: Page ID
fieldId: Field ID
fieldIdentifier: Field identifier
fieldPositionId: Field position ID
fieldRowId: Row ID (for table fields)
fieldColumnId: Column ID (for table fields)
fieldColumnIdentifier: Column identifier (for table fields)
e: Native DOM blur event
Example:
<JoyDoc
onBlur={(params, e) => {
console.log('Field blurred:', params.fieldId);
// Validate field on blur
validateField(params.fieldId);
}}
/>
onUploadAsync
- Triggered when: Images or files are uploaded
- Purpose: Handle file uploads to external storage or processing services
Event signature:
onUploadAsync(params, fileUploads) => {
// params contains upload context
// fileUploads contains the files to upload
// Must return array of file objects with url, fileName, filePath
}
Parameters:
params: Object containing upload context and document information
fileUploads: Array of file objects to upload
Return value: Array of file objects with:
url: Public URL of uploaded file
fileName: Name of the file
filePath: Path to the file
Example:
<JoyDoc
onUploadAsync={async (params, fileUploads) => {
console.log('Uploading files:', fileUploads);
const uploadPromises = fileUploads.map(async (file) => {
// Upload to your storage service
const uploadedFile = await uploadToS3(file);
return {
url: uploadedFile.url,
fileName: uploadedFile.fileName,
filePath: uploadedFile.filePath
};
});
return await Promise.all(uploadPromises);
}}
/>
onCaptureAsync
- Triggered when: Barcode is captured for table barcode cells
- Purpose: Handle camera capture functionality for barcode fields
Event signature:
onCaptureAsync(params) => {
// params contains capture context
// Must return URL string of captured barcode
}
Parameters:
params: Object containing capture context
Return value: String data of the captured barcode
Example:
<JoyDoc
onCaptureAsync={async (params) => {
console.log('Barcode capture initiated:', params);
// Open camera and capture barcode
const barcodeData = await captureBarcode();
return barcodeData;
}}
/>
onFileUploadAsync
- Triggered when: Images or files are uploaded
- Purpose: Handle field-specific file uploads with custom logic
Event signature:
onFileUploadAsync(params, fileUploads) => {
// params contains field and upload context
// fileUploads contains the files to upload
// Must return array of file objects with url, fileName, filePath
}
Parameters:
params: Object containing field information and upload context
fileUploads: Array of file objects to upload
Return value: Array of file objects with:
url: Public URL of uploaded file
fileName: Name of the file
filePath: Path to the file
Example:
// Configure in fieldSettings
const fieldSettings = {
field: {
onFileUploadAsync: async (params, fileUploads) => {
console.log('Field-specific upload:', params.fieldId, fileUploads);
// Custom upload logic for this specific field
const uploadPromises = fileUploads.map(async (file) => {
const uploadedFile = await customUploadService(file, params.fieldId);
return {
url: uploadedFile.url,
fileName: uploadedFile.fileName,
filePath: uploadedFile.filePath
};
});
return await Promise.all(uploadPromises);
}
}
};
<JoyDoc
fieldSettings={fieldSettings}
/>
onFileClick
- Triggered when: A file in a field is clicked
- Purpose: Handle file interactions like opening, previewing, or downloading
Event signature:
onFileClick(params, urlObject) => {
// params contains field and file context
// urlObject contains file information
}
Parameters:
params: Object containing:
fileId: File ID
pageId: Page ID
fieldId: Field ID
fieldIdentifier: Field identifier
fieldPositionId: Field position ID
urlObject: Object containing:
url: File URL
fileName: File name
filePath: File path
Example:
// Configure in fieldSettings
const fieldSettings = {
field: {
onFileClick: (params, urlObject) => {
console.log('File clicked:', urlObject);
// Open file in new tab
window.open(urlObject.url, '_blank');
}
}
};
<JoyDoc
fieldSettings={fieldSettings}
/>
onFileDelete
- Triggered when: A file in a field is deleted
- Purpose: Handle file deletion with cleanup or confirmation logic
Event signature:
onFileDelete(params, urlObject) => {
// params contains field and file context
// urlObject contains file information
}
Parameters:
params: Object containing:
fileId: File ID
pageId: Page ID
fieldId: Field ID
fieldIdentifier: Field identifier
fieldPositionId: Field position ID
urlObject: Object containing:
url: File URL
fileName: File name
filePath: File path
Example:
// Configure in fieldSettings
const fieldSettings = {
field: {
onFileDelete: async (params, urlObject) => {
console.log('File deleted:', urlObject);
// Show confirmation dialog
const confirmed = await showConfirmDialog(
`Are you sure you want to delete ${urlObject.fileName}?`
);
if (confirmed) {
// Delete from storage service
await deleteFromStorage(urlObject.filePath);
}
return confirmed;
}
}
};
<JoyDoc
fieldSettings={fieldSettings}
/>
onError
- Triggered when: Errors occur (schema validation, license validation, etc.)
- Purpose: Handle and display errors to users
Event signature:
onError(error) => {
// error contains error information
}
Parameters:
error: Object containing error information:
- For schema validation errors: Validation error details
- For license errors:
{ code: 'LICENSE_VALIDATION_ERROR', message: string, type: 'license' }
Example:
<JoyDoc
onError={(error) => {
console.error('JoyDoc Error:', error);
if (error.type === 'license') {
showLicenseError(error.message);
} else {
showGenericError('An error occurred. Please try again.');
}
}}
/>
Complete Example
Here’s a complete example showing how to use all events:
import React, { useState } from 'react';
import JoyDoc from './JoyDoc';
const MyJoyDocApp = () => {
const [doc, setDoc] = useState(initialDoc);
const [isLoading, setIsLoading] = useState(false);
const fieldSettings = {
field: {
onFileUploadAsync: async (params, fileUploads) => {
setIsLoading(true);
try {
const uploadPromises = fileUploads.map(async (file) => {
const uploadedFile = await uploadToS3(file);
return {
url: uploadedFile.url,
fileName: uploadedFile.fileName,
filePath: uploadedFile.filePath
};
});
return await Promise.all(uploadPromises);
} finally {
setIsLoading(false);
}
},
onFileClick: (params, urlObject) => {
window.open(urlObject.url, '_blank');
},
onFileDelete: async (params, urlObject) => {
const confirmed = await showConfirmDialog(
`Delete ${urlObject.fileName}?`
);
if (confirmed) {
await deleteFromStorage(urlObject.filePath);
}
return confirmed;
}
}
};
return (
<div>
{isLoading && <div>Uploading...</div>}
<JoyDoc
doc={doc}
fieldSettings={fieldSettings}
onChange={(changelog, updatedDoc) => {
console.log('Document changed:', changelog);
setDoc(updatedDoc);
saveDocument(updatedDoc);
}}
onFocus={(params, e) => {
console.log('Field focused:', params.fieldId);
analytics.track('field_focused', params);
}}
onBlur={(params, e) => {
console.log('Field blurred:', params.fieldId);
validateField(params.fieldId);
}}
onUploadAsync={async (params, fileUploads) => {
const uploadPromises = fileUploads.map(async (file) => {
const uploadedFile = await uploadToS3(file);
return {
url: uploadedFile.url,
fileName: uploadedFile.fileName,
filePath: uploadedFile.filePath
};
});
return await Promise.all(uploadPromises);
}}
onCaptureAsync={async (params) => {
const barcodeData = await captureBarcode();
return barcodeData;
}}
onError={(error) => {
console.error('JoyDoc Error:', error);
showError(error.message || 'An error occurred');
}}
/>
</div>
);
};
Best Practices
- Async Event Handlers: Always use
async/await for upload and capture events
- Error Handling: Implement proper error handling in all async event handlers
- Loading States: Show loading indicators during file uploads
- Validation: Use
onBlur for field validation
- Analytics: Use
onFocus and onChange for user interaction tracking
- File Management: Implement proper cleanup in
onFileDelete handlers
- Performance: Debounce
onChange events if needed for frequent updates