> For the complete documentation index, see [llms.txt](https://docs.agilecase.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.agilecase.com/developer-documentation/case-scripting/on-save-scripts/examples/handling-a-form-submission.md).

# Handling a Form Submission

Where a form is filled in over several sittings, the useful trigger is not any individual answer but the moment somebody declares it finished. A status field offering Submit and Save for later gives you that moment, and everything the submission should set off hangs off the one change.

This is the largest shape an on save script takes. A single Submit can confirm to the person who sent it, derive values from what they answered, copy answers onto the record, stamp a received date, and tell another system. It is worth reading as much for how the work is ordered as for what it does.

## The scenario

A policyholder completes a first notification of loss. On submission they get a confirmation, the total loss is worked out across several fields, a senior review is flagged where the claim warrants it, the received date is stamped, and the insurer's portal is notified if the case is set up for it.

| Setting       | Value                                                                           |
| ------------- | ------------------------------------------------------------------------------- |
| Trigger field | `5310` FNOL status (`Submit` / `Save for later`)                                |
| Loss fields   | `5311` Estimated loss, `5312`–`5314` Other known losses                         |
| Read          | `5315` Property occupied, `5316` Send to insurer portal, `5317` Cover confirmed |
| Written       | `5318` FNOL received (date), `5319` Senior review required                      |
| Template      | `FNOL-PolicyholderConfirmation`                                                 |
| Webhooks      | `InsurerPortal.FNOLAccepted`, `InsurerPortal.SeniorReviewRequired`              |

## The script

```javascript
[Changed.CustomField(5310).Changed]

function after_save() {
    if (Changed.CustomField("5310").NewValueAsText != "Submit") {
        Service.AddMessage("Your answers have been saved. Remember to submit them when you are ready.", "notify-info");
        return true;
    }

    // Blank optional fields read as NaN, which would poison the total
    function amount(fieldId) {
        var value = parseFloat(Service.CustomField(fieldId).ValueAsText);
        return isNaN(value) ? 0 : value;
    }

    var estimatedLoss = amount("5311");
    var totalLoss = estimatedLoss + amount("5312") + amount("5313") + amount("5314");
    var occupied = Service.CustomField("5315").ValueAsText;

    var seniorReview = "No";
    if (occupied == "No" || totalLoss > 25000 || estimatedLoss > 50000) {
        seniorReview = "Yes";
    }

    Service.AddMessage(
        "Thank you for submitting your claim notification.\nWe will start assessing the information you have provided.",
        "success");
    Service.SendEmail("FNOL-PolicyholderConfirmation");

    Service.UpdateCustomField("5319", seniorReview);
    Service.UpdateCustomField("5318", Service.GetCurrentDate());

    if (Service.CustomField("5316").ValueAsText == "Yes"
        && Service.CustomField("5317").ValueAsText == "Yes") {
        Service.SendWebhook("InsurerPortal.FNOLAccepted");

        if (seniorReview == "Yes") {
            Service.SendWebhook("InsurerPortal.SeniorReviewRequired");
        }
    }

    return true;
}
```

## Dealing with Save for later first

The script handles the case it is not interested in immediately and returns, which leaves the rest of the function free of the one condition that would otherwise wrap all of it. Anything else the submission needs can be added without another level of indentation.

Save for later still acknowledges the save. Somebody part-way through a form needs to know their answers were kept and that they have not yet submitted, and the reminder is cheap to include.

## Adding up optional fields

Three of the four loss fields are optional, and that is enough to break a total:

```javascript
// If 5313 is blank, totalLoss is NaN and every comparison below is false
var totalLoss = parseFloat(a) + parseFloat(b) + parseFloat(c);
```

`parseFloat("")` gives `NaN`, and `NaN` added to anything is `NaN`. No error is raised: the total silently becomes not-a-number, every comparison against it is false, and no claim is ever flagged for review. The `amount` helper reads each field once and substitutes zero for anything unreadable, so a blank field contributes nothing rather than destroying the sum.

The helper also uses `parseFloat` over `ValueAsText` rather than `ValueAsNumber`, because these are money fields.

{% hint style="warning" %}
`ValueAsNumber` handles whole numbers only, so a field holding `12500.50` reads as `0`. Any calculation over money or measurements should read `ValueAsText` and convert it.
{% endhint %}

## Deriving the flag before using it

`seniorReview` is worked out once, then used twice: written to `5319` so it is visible on the case and reportable, and consulted again to decide whether the second webhook goes out.

That is the part worth copying. Working the rule out in one place means the field on the case and the event sent to the insurer can never disagree. Testing the same three conditions again lower down would let the two drift apart the first time somebody adjusts one of them.

## Ordering the work

Nothing in the queue happens as it is called. Calls are collected and carried out in a fixed order once the function returns `true`, so the sequence in the script is for the reader rather than the runtime. What it does convey is intent: confirm to the customer, record what was decided, then tell the outside world.

The two webhooks sit behind both a configuration flag and a business condition. `5316` decides whether this case sends to the portal at all, `5317` that cover has been confirmed, and only then does the derived flag decide whether the more specific event follows the general one.

## Submitting twice

The trigger only fires when the status changes, so re-selecting Submit does nothing. Going from Submit to Save for later and back does fire it again, which sends a second confirmation and a second webhook.

If that matters, gate the whole thing on the received date instead of relying on users:

```javascript
if (Service.CustomField("5318").ValueAsText !== "") {
    Service.AddMessage("This notification has already been submitted.", "warn");
    return true;
}
```

Because `5318` is only stamped on a successful submission, it is a reliable record of whether the work has been done. Any script that sends something to a customer or another system is worth making safe to run twice.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.agilecase.com/developer-documentation/case-scripting/on-save-scripts/examples/handling-a-form-submission.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
