> 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/custom-form-scripting.md).

# Custom Form Scripting

A JavaScript label is a custom field whose value is a script rather than something a user types. The script runs in the browser while the user is on the tab that holds it, and it re-runs every time any field on that tab changes. That is what makes it the right tool for anything that has to keep up with what the user is typing: a running total, an age derived from a date of birth, a colour that follows a dropdown.

It is the narrowest of the scripting options, and deliberately so. The script only sees the tab it lives on, and what it produces is displayed rather than stored.

{% hint style="info" %}
Creating the field itself is covered in [JavaScript Label](/administrator-documentation/types-of-custom-field/javascript-label.md) in the administrator documentation. This page covers writing the script that goes in it.
{% endhint %}

## When it runs

The script runs twice over, in effect:

* Once when the tab is first rendered, so the field is populated as soon as the user arrives.
* Again on every change to any input, dropdown or text area on the same form.

There is no need to bind your own change handlers. Write the script as though it calculates the answer from scratch each time, and AgileCase will call it whenever anything might have moved.

## Reading and writing fields

Every custom field on the tab has a predictable element ID: `CustomField_` followed by the field's numeric ID. So a field with ID 6040 is read with:

```javascript
var dob = $('#CustomField_6040').val();
```

Your JavaScript label has its own element too, and that is where you put the result. The variable `ScriptID` is set to the label field's own ID before your script runs, so you can write to it without hardcoding the number:

```javascript
$('#CustomField_' + ScriptID).html(age);
```

Writing to the label's own element with `.html()` is the normal pattern. You can also reach the other fields on the tab to restyle or disable them, which is how the dropdown colour example works.

<table><thead><tr><th width="200">Available</th><th>Notes</th></tr></thead><tbody><tr><td>jQuery</td><td><code>$</code> is available, and your script already runs at the right moment. No ready wrapper needed.</td></tr><tr><td><code>ScriptID</code></td><td>The numeric ID of the JavaScript label field running the script.</td></tr><tr><td><code>#CustomField_&#x3C;id></code></td><td>The input for any custom field on the tab, and the output span for the label itself.</td></tr><tr><td><code>caseid</code></td><td>Available when the tab is on a case page, so a script there can also call the <a href="/pages/ZQDXBT5ispKejoaCxudN">Case Data API</a>. It is not available on contact tabs.</td></tr></tbody></table>

## What it cannot do

A JavaScript label produces a display value, not a stored one. Nothing it calculates is written to the database, which has consequences worth knowing before you choose this approach:

* The result is not available to reports.
* The result is not available as a merge field in document or email templates.
* The result is not visible to on save scripts or webhooks.

If the calculated value needs to survive beyond the screen, you want a [Calculated Field](/administrator-documentation/types-of-custom-field/calculated-fields.md) for a server-side calculation, or an [on save script](/developer-documentation/case-scripting/on-save-scripts.md) writing into a real field.

{% hint style="warning" %}
Errors in a JavaScript label are caught and written to the browser console rather than shown on screen. A broken script looks like a field that stays empty. If nothing appears, open the browser console before assuming the field is misconfigured.
{% endhint %}

Because the script runs on every change, keep it cheap. Avoid synchronous requests, and be careful with API calls, which will be repeated on every keystroke that fires a change.

## Examples

<table data-view="cards"><thead><tr><th>Example</th><th>What it shows</th><th data-card-target data-type="content-ref">Target</th></tr></thead><tbody><tr><td><strong>Calculating Age From Date of Birth</strong></td><td>Reading a date field and displaying a derived value in the label.</td><td><a href="/pages/wZyYqj5KTCfnSKtHZEcu">/pages/wZyYqj5KTCfnSKtHZEcu</a></td></tr><tr><td><strong>Changing Colours in a Dropdown Menu</strong></td><td>Restyling another field on the tab based on its selected value.</td><td><a href="/pages/ljCKV1tsxrShNHjxv3z3">/pages/ljCKV1tsxrShNHjxv3z3</a></td></tr></tbody></table>


---

# 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/custom-form-scripting.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.
