Script samples
- Copy a value from one field to another
- Calculate sum (difference, percentage) of multiple fields
- Write a value from a catalog column to a form field
- Search for duplicate entries in the register
- Deadline extension depending on priority
- Automatically change task status after receiving a reply
- Autocomplete service level agreement resolution time
- Filter a catalog
- Make sure the end date isn’t before the start date
- Make sure at least one field is filled out
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];
});
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.
form.onChange(['Catalog'])
.setValue('Text', state => {
const [item] = state.changes;
if (!item || !item.columns)
return null;
return item.columns['Column'];
});
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 || !year.text || !num.text)
return null;
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 && customDue.date)
return {date: customDue.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)
.setStatus(state => {
if (state.commenter && state.commenter.organization_id !== orgId)
return {choice_name: 'In progress'};
});
form.onChange(['Responsible'])
.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;
}
default:
return undefined;
}
}
Filter a catalog
To show only the cities of the selected state in the City field, use getCatalog with a server-side filter together with setFilterAsync. You might also use this approach to show the expenses related to a specific department chosen from a list of other departments. The full script, a description of the source catalogs, and an explanation of the result are in Catalogs.
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 (start.date && end.date && start.date >= end.date)
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;
});