Forms
The ComPDF Flutter SDK supports form callbacks and listener events for form style panels, field creation, field selection, and field deselection.
Available Callbacks and Events
| Type | Name | Trigger Timing | Payload |
|---|---|---|---|
| Reader callback | onFormStyleDialogDismissedCallback | Form style dialog is dismissed | CPDFFormType type |
| Reader callback | onInterceptWidgetActionCallback | A configured form widget is tapped and interception is enabled | CPDFWidget widget |
| Listener event | CPDFEvent.formFieldsCreated | Form field is created | CPDFWidget |
| Listener event | CPDFEvent.formFieldsSelected | Form field is selected | CPDFWidget |
| Listener event | CPDFEvent.formFieldsDeselected | Form field is deselected | CPDFWidget? |
Form Widget Action Intercept
Use form widget action interception when you want to replace the SDK's default form field tap behavior with your own UI or business logic. You can intercept all form widget actions with interceptAllFormWidgetActions, or intercept only selected widget types with interceptFormWidgetActions.
The recommended approach is to intercept only the widget types that need custom handling:
final configuration = CPDFConfiguration(
formsConfig: const CPDFFormsConfig(
interceptFormWidgetActions: [
CPDFFormType.textField,
CPDFFormType.checkBox,
CPDFFormType.listBox,
CPDFFormType.comboBox,
],
),
);Handle the intercepted widget in CPDFReaderWidget.onInterceptWidgetActionCallback. If you change a widget value, call updateWidget to apply the custom result to the document.
CPDFReaderWidget(
document: documentPath,
configuration: configuration,
onCreated: (controller) {
readerController = controller;
},
onInterceptWidgetActionCallback: (CPDFWidget widget) async {
switch (widget.type) {
case CPDFFormType.textField:
final textWidget = widget as CPDFTextWidget;
textWidget.text = 'Handled by Flutter';
await readerController.document.updateWidget(textWidget);
break;
case CPDFFormType.checkBox:
final checkBox = widget as CPDFCheckBoxWidget;
checkBox.isChecked = !checkBox.isChecked;
await readerController.document.updateWidget(checkBox);
break;
case CPDFFormType.listBox:
final listBox = widget as CPDFListBoxWidget;
listBox.selectItemAtIndex = 0;
await readerController.document.updateWidget(listBox);
break;
case CPDFFormType.comboBox:
final comboBox = widget as CPDFComboBoxWidget;
comboBox.selectItemAtIndex = 0;
await readerController.document.updateWidget(comboBox);
break;
default:
break;
}
},
);To intercept every form widget type, set interceptAllFormWidgetActions: true. Use it only when your app provides complete custom behavior for all form widgets.
Example Usage
late CPDFReaderWidgetController readerController;
void onFormFieldCreated(dynamic widget) {
debugPrint('Form field created: $widget');
}
void onFormFieldSelected(dynamic widget) {
debugPrint('Form field selected: $widget');
}
void onFormFieldDeselected(dynamic widget) {
debugPrint('Form field deselected: $widget');
}
CPDFReaderWidget(
document: documentPath,
configuration: configuration,
onCreated: (controller) {
readerController = controller;
readerController.addEventListener(CPDFEvent.formFieldsCreated, onFormFieldCreated);
readerController.addEventListener(CPDFEvent.formFieldsSelected, onFormFieldSelected);
readerController.addEventListener(CPDFEvent.formFieldsDeselected, onFormFieldDeselected);
},
onFormStyleDialogDismissedCallback: (CPDFFormType type) {
debugPrint('Form style dialog dismissed: ${type.name}');
},
);Remove Event Listeners
readerController.removeEventListener(CPDFEvent.formFieldsCreated, onFormFieldCreated);