DocView Capture by DocView.AI3 Nov 2026 09:42

JavaScript event scripts

Event scripts are short pieces of JavaScript that run while an operator works on a batch. They react to things that happen on the Index / Validate screens: a batch opens, a document is shown, a field gets or loses the cursor, a value changes, a button on the form is pressed, a document is completed or the batch is released.

Use them to format values, fill one field from others, move the cursor, show a warning, stop an operator completing a document that is not right, or add line items with one click.

Where you write them

Event scripts belong to a Batch Setup version. You can edit them in three places:

  • the Batch Setup's Events tab, which lists all of them;
  • the Scripts panel of the screen designer, for a document class's document, field and button scripts;
  • the field editor, for the field's own scripts.

All three use the same editor. It colours the code, checks for errors, and offers IntelliSense for the variables and your Batch Setup's field names.

Add an event script

  1. Open the Batch Setup, work on a draft version, and open the Events tab.
  2. Click Add and fill in:
    • Name;
    • Event: see the list below;
    • Document class: All classes, or one class;
    • Field or Fields of the group, for field and field-group events;
    • Runs: In the browser or On the server;
    • Enabled.
  3. Write the Script.
  4. Under Try it, type field values, one per line as Name = value, and click Try.
  5. Click Save events.

Click Help in the editor for a summary of events, variables and results.

Browser or server

In the browser On the server
Speed Instant, no network round trip. A call to the server.
Best for BeforeFocus, LostFocus and Change: formatting, filling fields, moving the cursor. Checks that must not be bypassed, and AfterRelease.
Sandbox A dedicated Web Worker with no network access and no access to the page, cookies or server. Stopped after 1.5 seconds. DocView Capture's JavaScript sandbox: strict mode, no .NET, file or network access, stopped after 2 seconds or 500,000 statements, 64 MB memory.

Server Validate scripts run wherever documents are checked: after extraction, on every save and when a document is completed. So a rule written as a server Validate script cannot be skipped.

Try it runs the script on the server. Browser scripts use the same variables and results, so they behave the same.

Events

Scope Event When it runs
Batch Open The batch is opened on the Index / Validate screen.
Batch Close The operator closes the batch (Save & close, Next batch).
Batch BeforeRelease The operator releases the batch. Can stop the release.
Batch AfterRelease The batch was released. Server only, for example to log or notify.
Batch Route A workflow step was completed. Server only. Can send the batch to another step. See Route the batch.
Batch ArrangePages A workflow step was completed, before the next step is chosen. Server only. Can split, cut out, turn, copy, move or delete pages and start new documents. See Arrange pages and documents.
Document Load A document is shown to the operator.
Document Close The operator moves from the document to another one.
Document Validate The document is checked: when it is completed, and on the server after every change.
Document BeforeComplete The operator completes the document. Can keep it open.
Document Click The operator presses a form button that runs this script.
Field BeforeFocus The cursor is about to enter the field.
Field LostFocus The cursor leaves the field.
Field Change The value was changed (typed, picked or clicked on the image).
Field Validate The field is checked after a change and when the document is completed.
Field group Change Any of the group's fields was changed.
Field group Validate The group is checked after a change and when the document is completed.

Buttons are added to a form in the screen designer (Workflow tab › Design screens). Each button names the Click script it runs. See Screen designer.

What a script can use

The script body runs as a function, so you can use return.

Variable Contents
event { name, scope, script }: which event is running, and the script's name.
field { name, value, previous }: the field of a Field or Field group event.
fields All fields of the document by name, for example fields.TotalAmount. For batch events, the batch fields.
tables Line items by table name, for example tables.LineItems[0].Amount.
document { number, className, pages, state }. className is the document class key.
batch { name, fields, documentCount, pageCount }.
user The operator's user name.
num(text) Reads an amount such as £1,250.00 as a number.
round(n, digits) Rounds a number.
inDictionary(name, value) Server scripts only. true when the value is an entry of the dictionary.
translate(name, value) Server scripts only. The entry's value from the dictionary, or null.

Field values are text. Use num() before you calculate.

What a script returns

Return value Effect
nothing, or true No effect.
'a message' Shows the message. For Validate, BeforeComplete and BeforeRelease it is an error that stops the action.
false Stops the action (BeforeComplete, BeforeRelease) or fails Validate.
{ set: { Field: value } } Changes field values.
{ setBatch: { Field: value } } Changes batch field values.
{ setTables: { Table: [ { Column: value } ] } } Replaces the rows of a table.
{ action: 'complete' } For buttons: then complete the document. Also 'next', 'previous', 'save' (save and close) or 'release'.
{ message, severity } Shows a message. severity is 'info', 'warning' or 'error'.
{ errors: { Field: 'text' } } Marks fields as wrong with a message.
{ focus: 'Field' } Puts the cursor in a field.
{ cancel: true } Stops the action, for events that can be stopped.

You can combine properties in one object, for example set, message and action.

Examples

Field · Change (browser): upper case and no spaces

return { set: { [field.name]: (field.value || '').toUpperCase().replace(/\s+/g, '') } };

Field group · Change (browser): fill the total

if (!fields.TotalAmount && fields.NetAmount && fields.VatAmount) {
    return { set: { TotalAmount: round(num(fields.NetAmount) + num(fields.VatAmount), 2).toFixed(2) } };
}

Field · LostFocus (browser): jump to the PO number when it is needed

if (field.value && !fields.PoNumber) {
    return { focus: 'PoNumber', message: 'This supplier needs a PO number.', severity: 'warning' };
}

Document · BeforeComplete (server): stop credit notes without a reference

if (document.className === 'credit_note' && !fields.PoNumber) {
    return 'A credit note needs the original invoice or PO reference.';
}

Document · Click (button): add a delivery line, then complete

const lines = (tables.LineItems || []).concat([{ Description: 'Delivery', Quantity: '1', Amount: '25.00' }]);
return {
    set: { Currency: 'GBP' },
    setBatch: { Reference: fields.Supplier },
    setTables: { LineItems: lines },
    message: 'Delivery added.',
    action: 'complete'
};

Batch · BeforeRelease (server): at least one document

return batch.documentCount > 0 || 'The batch has no documents.';

Arrange pages and documents

An ArrangePages script (Batch scope, on the server) rearranges a batch whenever a step is completed — also when an import releases a batch past Scan straight away. Use it for what separation rules and image steps cannot do: split an A3 sheet into A4 pages, cut a cheque off a page, turn pages, copy a page into two documents, delete pages, or group pages into documents your own way.

The script sees:

  • step — completed (the step's name), module (for example scan) and next.
  • batch — name, priority, source and fields.
  • pages — each page in order: id, number, document (its document's number, or null), widthMm, heightMm, size (A5, A4, A3, A2, Letter, Legal, Tabloid or other, either way round), landscape, side (front, back or null), sheet, blank and sourcePage.
  • documents — each document: number, className and pages (the ids of its pages).

It returns nothing to leave the batch as it is, or:

{ documents: [ [ /* pages of document 1 */ ], [ /* document 2 */ ] ], loose: [ /* pages in no document */ ], delete: [ /* page ids */ ], reason: 'why' }

Each page in the lists is a page's id (or its number), or an object { page: id, part: 'left', rotate: 90 }:

  • part — left, right, top or bottom: half of the page. On a page standing upright, left and right are its top and bottom half, so left is always the first half of the sheet.
  • crop — any part of the page: { x: 0.1, y: 0.5, w: 0.8, h: 0.3 } in fractions of the page.
  • rotate — 90, 180 or 270 degrees clockwise.

Helpers: part(page, 'right'), rotate(entry, 90) and isSize(page, 'A3').

Every page must be placed in a document, left loose or deleted, or the script fails and the batch waits in the exception queue — so a script cannot lose pages by mistake. A page used only in parts is replaced by its parts; the same page placed twice is copied. The existing documents are kept in order (with their type and values) as far as the script returns documents; extra documents are added and documents left over are removed. The batch history records what was done.

Example: A3 sheets as A4 pages. Each A3 sheet starts a document; its front and back become four A4 pages in the order of a folded booklet (front right, back left, back right, front left), and the A4 pages scanned after it stay in its document. Put it on the Batch Setup's Events tab, Batch scope, event ArrangePages, run on the server:

if (step.module !== 'scan') return;            // only once, when the batch leaves Scan
var docs = [], doc = null;
for (var i = 0; i < pages.length; i++) {
    var p = pages[i];
    if (isSize(p, 'A3')) {
        // The next A3 page is the sheet's back (unless it is the front of another sheet).
        var back = i + 1 < pages.length && isSize(pages[i + 1], 'A3') && pages[i + 1].side !== 'front' ? pages[++i] : null;
        doc = [part(p, 'right')];
        if (back) { doc.push(part(back, 'left'), part(back, 'right')); }
        doc.push(part(p, 'left'));
        docs.push(doc);
    } else {
        if (!doc) { doc = []; docs.push(doc); }   // A4 pages before the first A3 sheet
        doc.push(p.id);
    }
}
return { documents: docs, reason: 'A3 sheets as A4 pages' };

Switch off blank page deletion for such a Batch Setup when every side must be kept.

This example is ready to try as the template A3 sheets as A4 pages (script) on the System features tab of New Batch Setup, with sample files to download; Tidy pages with a script shows deleting blank pages and turning pages upright.

Good practice

  • Keep browser scripts short. They must finish within 1.5 seconds.
  • Put checks that must always hold into server Validate or BeforeComplete scripts.
  • Return values as text, for example total.toFixed(2).
  • Prefer validation rules for standard checks such as totals and check digits. Use scripts for what rules cannot express.
  • Server script errors are shown to the operator with the script's name. Errors in AfterRelease scripts, when no operator screen is left, are recorded in the audit log as EventScriptError.

Still stuck? support@docview.ai · +44 7886 864921

Made with DocView Capture by DocView.AI · www.docview.ai