diff --git a/learn/how-tos/enable-async-callbacks-form.md b/learn/how-tos/enable-async-callbacks-form.md new file mode 100644 index 000000000..fc30f91c9 --- /dev/null +++ b/learn/how-tos/enable-async-callbacks-form.md @@ -0,0 +1,93 @@ +--- +title: "Enable Async Callbacks - Form" +id: "enable-async-callbacks-form" +--- + +The enableAsyncCallbacks property allows forms to wait for asynchronous operations (like encryption services) to complete before submission. This is useful when scripts need to perform data transformations that require processing time. + +### Configuration + +Set the enableAsyncCallbacks property to true in the form's properties panel: +```js +Enable Async Callbacks: true +``` + +### Usage + +When enableAsyncCallbacks is enabled, scripts must call widget.completeAsyncCallback() to signal completion: + +#### Example - Encrypting Password During Login + +```js +Page.loggedInUserForm1Beforesubmit = function ($event, widget, $formData) { + const currentPassword = $formData.j_password; + if (!currentPassword) { + return true; // Synchronous completion for no encryption + } + App.Variables.serviceVariable2.setInput('text', currentPassword); + + const originalOnSuccess = App.Variables.serviceVariable2.onSuccess; + const originalOnError = App.Variables.serviceVariable2.onError; + + App.Variables.serviceVariable2.onSuccess = function (variable, data) { + try { + const encryptedPassword = App.Variables.serviceVariable2.dataSet.value; + if (encryptedPassword) { + $formData.j_password = encryptedPassword; + + if (widget && widget.updateDataOutput) { + widget.updateDataOutput('j_password', encryptedPassword); + } + } + } catch (error) { + console.error('Error processing result:', error); + } + // Restore callbacks + if (originalOnSuccess) { + App.Variables.serviceVariable2.onSuccess = originalOnSuccess; + } + // Signal completion to the form component + widget.completeAsyncCallback(true); + }; + + + App.Variables.serviceVariable2.onError = function (variable, error) { + // Restore callbacks + if (originalOnError) { + App.Variables.serviceVariable2.onError = originalOnError; + } + console.log('Signaling completion due to error...'); + widget.completeAsyncCallback(false); + }; + // Start the async operation + App.Variables.serviceVariable2.invoke(); +}; +``` + +### Key Points + +1. **Default Behavior:** When enableAsyncCallbacks is false (default), forms submit immediately using synchronous behavior + +2. **Async Behavior:** When true, forms wait for widget.completeAsyncCallback() before submission + +3. **Required Method:** Scripts must call widget.completeAsyncCallback(true/false) to proceed + +4. **Data Updates:** Use widget.updateDataOutput(key, value) to update form data after async operations + +5. **Backward Compatible:** Existing forms continue to work unchanged + +### Methods + +#### widget.completeAsyncCallback(result) + +Signals completion of async operations: + +1. widget.completeAsyncCallback(true) - Continue with form submission +2. widget.completeAsyncCallback(false) - Prevent form submission + +#### widget.updateDataOutput(key, value) + +Updates form data after async operations: +```js +widget.updateDataOutput('fieldName', newValue); +``` \ No newline at end of file diff --git a/website/sidebars.json b/website/sidebars.json index 0ed044552..dec7b865d 100755 --- a/website/sidebars.json +++ b/website/sidebars.json @@ -1152,7 +1152,8 @@ "how-tos/get-validation-messages-form", "how-tos/form-conditional-flows", "how-tos/adding-master-detail-records-transaction", - "how-tos/adding-parent-child-records-single-transaction" + "how-tos/adding-parent-child-records-single-transaction", + "how-tos/enable-async-callbacks-form" ] } ]