> ## 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.

# Event Handling

This guide covers the event callbacks available in Joyfill forms and when they're triggered.

### **Available Events**

| Event     | When Triggered                         | Purpose                    |
| --------- | -------------------------------------- | -------------------------- |
| onChange  | Field value changes                    | Track form changes         |
| onFocus   | Field gains focus, or page gains focus | Handle field or page focus |
| onBlur    | Field loses focus, or page loses focus | Handle field or page blur  |
| onUpload  | File upload requested                  | Handle file uploads        |
| onCapture | Barcode scan requested                 | Handle barcode scanning    |

## **onChange Event**

Triggered when any field value changes in the form.

**Parameters:**

* changes: \[Change] - Array of change objects describing what was modified
* document: JoyDoc - The fully updated document with all changes applied

```swift theme={null}
func onChange(changes: [Change], document: JoyDoc) {        
     if let firstChange = changes.first {
           print(">>>>>>>>onChange", firstChange.change ?? "")
     }
     // The document parameter contains the fully updated form
}
```

## **onFocus Event**

Triggered when a field receives focus, or when a page becomes the current page (page focus).

**Parameters:**

* event: **Event** — Either a field focus or a page focus. Use `event.fieldEvent` for field focus, or `event.pageEvent` for page focus.

**Event properties:**

* `event.fieldEvent` — Set for field focus; contains `FieldIdentifier` (e.g. `fieldID`, `pageID`, `fieldPositionId`).
* `event.pageEvent` — Set for page focus; contains `PageEvent` with `type: "page.focus"` and `page: Page`.

```swift theme={null}
func onFocus(event: Joyfill.Event) {
    if let field = event.fieldEvent {
        print("Field focused: \(field.fieldID)")
    } else if let pageEvent = event.pageEvent {
        print("Page focused: \(pageEvent.page.id ?? "")")
    }
}
```

## **onBlur Event**

Triggered when a field loses focus, or when the user leaves a page (page blur).

**Parameters:**

* event: **Event** — Either a field blur or a page blur. Use `event.fieldEvent` for field blur, or `event.pageEvent` for page blur.

**Event properties:**

* `event.fieldEvent` — Set for field blur.
* `event.pageEvent` — Set for page blur; contains `PageEvent` with `type: "page.blur"` and `page: Page`.

```swift theme={null}
func onBlur(event: Joyfill.Event) {
    if let field = event.fieldEvent {
        print("Field blurred: \(field.fieldID)")
    } else if let pageEvent = event.pageEvent {
        print("Page blurred: \(pageEvent.page.id ?? "")")
    }
}
```

## **onUpload Event**

Triggered when a file upload is requested for image or file fields.

**Parameters:**

* event: UploadEvent - Upload event details

**Properties Available:**

* fieldEvent: FieldIdentifier - The field requesting upload
* multi: Bool - Whether multiple files are allowed
* uploadHandler: (\[String]) -> Void - Callback to provide file URLs

```swift theme={null}
func onUpload(event: UploadEvent) {
        print("📤 Upload requested for field: \(event.fieldEvent.fieldID)")
        
        // Option 1: Present a photo picker for the user to choose an image.
        // Option 2: Directly send pre-uploaded image identifiers or URLs to the upload handler.
        
        let exampleImageURL = "https://example.com/uploads/sample-image.jpg"
        
        // Example: sending a direct image URL or an identifier for the upload
        event.uploadHandler([exampleImageURL])
    }
```

## **onCapture Event**

Triggered when camera capture is requested for Barcode cell.

**Parameters:**

* event: CaptureEvent - Capture event details

**Properties Available:**

* fieldEvent: FieldIdentifier - The field requesting capture
* captureHandler: (ValueUnion) -> Void - Callback to provide captured content

```swift theme={null}
    func onCapture(event: Joyfill.CaptureEvent) {
        print("📷 Capture requested for field: \(event.fieldEvent.fieldID)")
        print("User can open a barcode scanner to capture the code.")
        event.captureHandler(.string("Scan Button Clicked"))
    }
```

## **onError Event**

* Used to listen to errors during document processing.
* error: JoyfillError — details about the failure.
* Error types include:
  * schemaValidationError — Document schema validation failures
  * schemaVersionError — SDK and document version compatibility issues

```swift theme={null}
func onError(error: Joyfill.JoyfillError) {
        switch error {
        case .schemaValidationError(let schemaError):
            print("❌ Schema Error: \(schemaError)")
        case .schemaVersionError(let versionError):
            print("❌ Schema Error: \(versionError)")
        }
        print("Error occurred: \(error)")
    }
```
