Script samples

Copy a value from one field to another

This script copies the value from “Source field” to “Text field”.

form.onChange(['Source field'], true)
  .setValue('Text field', state => {
    const [value] = state.changes;

    if (!value)
      return null;

    return value.text;

Calculate sum (difference, percentage) of multiple fields

In this example, the script adds up rental cost and deposit, then applies a 7% discount and displays this sum.

form.onChange(['Rental price', 'Deposit'])
  .setValues(['Discount', 'Total'], state => {
    const [price, deposit] = state.changes;

    if (!price || !deposit)
      return null;

    const discount = price.value * 0.07;
    const total = price.value + deposit.value - discount;
    return [discount, total];

Hide a field

In this example, the 'Discount' field is hidden if the value in the 'Quantity' field is up to 99.

form.onChange(['Quantity'], true)
  .setVisibility(['Discount'], state => {
    const [quantity] = state.changes;

    if (!quantity)
      return null;

    return quantity.value > 99;

Hide a field from a certain step

In the example below, the Client field will be hidden from the second step of the workflow.

form.onChange([''], true)
  .setVisibility (['Client'], state => {
    return state.currentStep < 2;

Write a value from a catalog column to a form field

Here “Catalog” is the name of the form field with a catalog, “Column” is the name of a catalog column, and “Text” is the **Text** type form field where the value is stored.

  .setValue('Text', state => {
    const [item] = state.changes;

    if (!item || !item.columns)
      return null;

    return item.columns['Column'];

Make sure the end date isn’t before the start date

form.onChange(['Start date', 'End date'])
  .validate('End date', state => {
    const [start, end] = state.changes;

    if (!start || !end)
      return null;

    if ( && && >=
      return {
        errorMessage: 'The end date cannot be before the start date.'

    return null;

Make sure at least one field is filled out

form.onChange(['Email', 'Phone'], true)
  .validate('Email', state => {
    const [email, phone] = state.changes;

    const emailIsEmpty = !email || !email.text;
    const phoneIsEmpty = !phone || !phone.text;

    if (emailIsEmpty && phoneIsEmpty)
      return {
        errorMessage: 'Add your email or phone number.'

    return null;

Search for duplicate entries in the register

Suppose there is a form with the fields “Year”, “Number”, and “Document”. Using this script, you can send a request to the register and check if the document has already been published.

form.onChange(['Year', 'Number'])
  .validateAsync('Number', async state => {
    const [year, num] = state.changes;

    if (!year || !num)
      return null;

    if (year.text && num.text) {
      const duplicates = await form.fetchSelfRegister(f => f
        .fieldEquals('Year', year)
        .fieldEquals('Number', num), []

      if (!duplicates || !duplicates.tasks)
        return null;

      const firstDuplicate = duplicates.tasks[0];
      if (firstDuplicate)
        return {
          errorMessage: `Order <a href="#id${firstDuplicate.task_id}">has already been published.</a>`

    return null;

Deadline extension by priority

This script lets you change a task's due date based on its priority, or set a custom due date.

form.onChange(['High priority', 'Date shifting'])
  .setValue('Due date', state => {
    const [checkmark, customDue] = state.changes;

    if (customDue &&
      return {date:};

    if (!checkmark)
      return null;

    if (checkmark.checked)
      return {days_from_create: 1};

    return {days_from_create: 3};

Automatically change task status after receiving a reply

const orgId = 111111;

form.onChange([], true)
  .setVisibility(['Open / Done'], 
    state => false

form.onChange([], true)
  .setStatus(state => {
    if (state.commenter && state.commenter.organization_id !== orgId)
      return {choice_name: 'In progress'};

  .setStatus(state => {
    const [currVal] = state.changes;
    const [prevVal] = state.prev;

    if (!prevVal && currVal)
      return {choice_name: 'In progress'};

Autocomplete service level agreement resolution time

You can specify resolution time and field names in the script using specific numbers,, variables, or formulas to calculate the resolution time. When the Priority and Client form fields are changed, the script will determine one of the designated due dates.

form.onChange(['Priority', 'Client'])
  .setValue('Due date', 
    state => {
      const [priority, client] = state.changes;

      if (!priority || !priority.columns || !client || !client.columns)
        return null;

      const tariff = client.columns['Rate plan'];
      const priorityValue = priority.columns['Priority'];
      const hours = getSlaHoursByTariffAndPriority(tariff, priorityValue);

      if (hours === undefined)
        return null;

      return {hours_from_create: hours};

function getSlaHoursByTariffAndPriority(tariff, priority) {
  switch (tariff) {
    case 'Basic':
      switch (priority) {
        case 'Low' : return 64;
        case 'Medium': return 32;
        case 'High': return 16;
    case 'Standard':
      switch (priority) {
        case 'Low' : return 32;
        case 'Medium': return 16;
        case 'High': return 8;
    case 'Premium':
      switch (priority) {
        case 'Low' : return 16;
        case 'Medium': return 8;
        case 'High': return 4;
      return undefined;

Hide a form field if an email doesn’t come not from a designated address

The script identifies the sender’s email address, and if a message is not from, the Category field will be hidden.

form.onChange(['Email'], true)
  .setVisibility(['Category'], state => {
    const [email] = state.changes;
    return email && email.text == "";

Filter a catalog

This script filters the list of cities by selected state. You might also use it to show the expenses related to a specific department chosen from a list of other departments.

let catalogItems = null;

form.getCatalog("US states and cities").then(items => {
  catalogItems = items;

form.onChange(["State"]).setFilter("City", state => {
  const [region] = state.changes;

  if (!catalogItems || !region || !region.columns)
    return null;

  const regionCol = region.columns["State"];
  const filtered = catalogItems
    .filter(item => item.columns["State"] == regionCol)
    .map(item => item.columns["City"]);
  return filtered.length > 0
    ? {
        values: filtered
    : null

Was this article helpful?

Yes, thanks! No, I have a question