Salesforce

Calculations (Form Functions)

« Go Back
Information
Calculations (Form Functions)
calculations-form-functions
Article Details

Introduction

Calculations are powerful. In addition to enabling calculations relating to date/number fields, they can also be used for validating data etc, below you will find worked examples and ideas, along with syntax.


Example Calculations

Attached is a form that we advise you to import into your Forms product which shows an array of calculations/functions available.

This includes;

  • Detailed information on the contains function
  • Some Example if statements
  • Methods for manipulating strings
  • Date Formats (Note: time and datetime fields always STORE the seconds, even if not shown eg HH:MM, therefore when calculating with time fields need to include SS in calculations)*
  • Repeatable Subform equations.
  • Some useful tricks 
  • A full list of logical operations.
  • Keyword list
  • Function list

To use this form properly, import it and Fill in the sections to find the calculation type you are looking for.  Then go to 'Edit' to see how it was set up.  The examples will help with defining your own required calculations


Using A Mathematical Calculation in a Form

The Form Designer can set up a calculated field by entering the mathematical formula into the “Default Value” field. Other fields on the form can be referenced by using their dataname in curly braces {}

They can perform mathematical operations on Number, Text and Date fields. They can be used to calculate costs, totals, or other more complex expressions.

eg in this example the number in the "distance" field will be multiplied by 0.34:

 {distance}*0.34

If a repeating field is referenced, the value returned will be the sum of the values in the field. Other aggregate functions, such as “count” can be referenced. The following example calculates the average value in a repeating field:

 sum({myfield})/count({myfield})

To calculate the totals from a select many (only works where the values of each item in the select many are unique)

  sum({selectmany})

Most calculations will be dependent on the usage of tokens which are the value place holders in curly parenthesis, for example '{myfield}'. 

Complex Calculations

Avoid using lengthy calculations as these are likely to introduce syntax errors and make solving the issue difficult, when calculating a fee payable based on a series of select 1 fields there is a natural tendency to build a beast of a calculation based on an if statement, we would avoid such scenarios, and suggest 

  • Use "helper" fields to break the calculations into smaller more manageable chunks, this enables each element to be checked for syntax
  • For fee structures it is advisable to hold the fee table in a database with start and end dates
    This allows for future planning when fees change year on year, and removes the pressure of amending complex calculations out side of normal working hours. 
    It also ensure that fees are calculated correctly depending on both when the request/order is placed and the date from which the order/service will be supplied (no beating the system by placing a order a few days before the price goes up).  The correct fees can then be pulled into form from a lookup.

Using Calculations to Manipulate Text

Calculations can be used to control messages or the way text appear to the users or is presented for integrations, eg

  • Joining two or more fields/tokens together to create a text string - using ???concat({something},' ',{somethingelse})

    For example an address string can be created using 

     concat((if({house}<>'',{house},'')),(if({house}<>'',',','')),' ',(if({flat}<>'',{flat},'')),(if({flat}<>'',',','')),' ',{street},',',' ',{town},',',' ',{postcode}) 
  • Building a response based on one or more tokens
     "Your "+{application_type}+" request will receive a response by "+{deadline}

    Or;

     concat({fielda},' ',{fieldb}) 

    Concat is recommended for numeric fields, + is easier but relies on the fields concerned to be textual.  To add a line break between two fields (Text Area fields)
    You can use;

     {text1}+' \n' +  {text2}
  • Calculations can be used to display specific messages to the form filler based on previously completed fields

     if( {tree} is 'yes' and {bench} is 'yes' and {lamppost} is 'yes' ,'One sentence can be displayed','Or another can be displayed')
    But if calculation is more complex then often better to use brackets to ensure calculation is actioned in correct order
      if(({fieldOne} = '1' && {fieldTwo} = 'something'),'Display message 1','message 2')
  • It is sometimes easier to manipulate the text to be displayed for an email or printable within the form itself using an "if calculation" rather than build complex af:if statements
     
  • Calculations can be used to create standard text for emails/PDFs - using a combination of the above and HTML fields it is possible to create a standard output for each form/process whic can then be dropped into a generic email/Printable reducing the over head for these.
     
  • Calculations can also be used to create specific redirect URLs 

Using Calculations to validate

Calculations can be used to validate entries and give specific warnings to the form filler

 if( {tree} is 'yes' and {bench} is 'yes' and {lamppost} is 'yes' ,'valid','invalid')

which returns true/false in the field if used as a default value 
Statements defining valid status can be added in Validation Condition eg {text3}='true'  - if the field is not true then the Validation condition message will be displayed.  In many cases the simple calculation to define valid status can simply be added in a validation condition box

 


Logic Operators

Any of the following operators and functions can be used in a calculated field:

Logical Operator

Description

Logical Operator

Description

+

Add.

<=

Less than or equal to.It can also be used the operator lte

-

Subtract.

>=

Greater than or equal to. It can also be used the operator gte

*

Multiply.

is

Equal to

=

equal

isnt

Not equal to.

===

triple equal . It also can be used the operator “is”

(equal value & type)

&&

and. it also can be used the operator “and”
Please note this must be lowercase

!=

Not equal to.

||

or. It can also be used the logic operator “or”
Please note this must be lowercase

!==

Not equal to.

contains

contains. See the example below for more information

<>

Not equal to. The same as the operator !=

icontains

case insensitive contains.

/

Divide.

notcontains

not contains

mod

Modulo.

noticontains

not contains case insensitive

<

Less than.It can also be used the operator lt

match

matches an expression

>

Greater than.It can also be used the operator gt

notmatch

doesn't match an expression

 

Examples:

  1. The following example depicts the  display condition of a field, using  some of the previous operators. In this case,  the field will be displayed whether  the fields number1 is less than number2 and the field text1 contains the word “test“ ,or in the case that the field {text2} is “Firmstep”
 ({number1} < {number2} && {text1} contains 'test')    ({text2} is 'Firmstep')
  1. Given the field text2 "AAQ978A&%" the following expression will be evaluated as true
 {text2} match '[^A-Za-z0-9_]'

See regex note below - when using regex statements

    3. The following example if statement can be used to indicate this week/next week, Using a select field {date} and a cut off time field {time1} of HH:MM*

 if({day} is 'Tuesday' and {time1} <'17:15:00' ,'This week','Next week')

 Detailed examples are available in the attached functions demo form

When using display conditions, AND and OR have to be as and, or lowercase for this to work.

top of page


Keywords

Keywords are special words which can be used in calculations.*

Keyword

Description

days

Used in date calculations to add a specific numbers of days to a given date. For example:

To add seven days to a date field called Order Date with the calculation would be {Order_Date}+7 days.

Please note that this keyword cannot be used in a DateDiff function. See the Functions table below for available parameters. Note when using negative numbers, a plus sign is still required - e.g. "format((now + -6 months),'%Y-%m-%dT%T')"

hoursUsed in date calculations to add a specific number of hours to a given time.  For example
(time}+ 7 hours

months

Used in date calculations to add a specific numbers of months to a given date. For example:

To subtract three months from a date field called Delivery Date the calculation would be {Delivery_Date}-3 months.

Please note that this keyword cannot be used in a DateDiff function. See the Functions table below for available parameters.  

now

Returns the current date and time. Is used in the DateDiff function. It allows date calculations to be performed without a second date field on the form. For example:

To calculate the difference in days between the current date and a date field called Collection Date, the DateDiff function is used with the now key word. The calculation is DateDiff(d, {now}, {date1}).

randomstring

Returns an 13 -character securely-generated random string (alphanumeric)

workdays

Used in calculations and date fields to add working days (Monday - Friday) to a date. 

 {today} + 10 workdays

(Note this does not exclude all bank holidays - from our testing, Christmas/Boxing/New Year's Day, as well as May Day and Easter, are excluded - there is no workaround to achieve working days excluding other bank holidays).

years

Used in date calculations to add a specific numbers of years to a given date. For example:

To add a year from a date field called Purchase Date the calculation would be {Purchase_Date}+1 years.

Please note that this keyword cannot be used in a DateDiff function. See the Functions table below for available parameters.

top of page


Functions

There are a number of built in functions to add more flexibility to calculations.

Function

Syntax

Description

count

count({field})

Counts the number of instances of a repeating subform or the number of uploads in an upload fields.

datediffdatediff(<d m y>,{date1},{date2})

Returns the number of time periods between date1 and date2. If date1 is later than date2 then the result will be positive. 

The time period can be 'd', 'm', 'y', or 'fy'.

'fy' = full year - useful for calculating age from a DOB. E.g.  datediff(fy,{today},{dateOfBirth})

'fm' = full month - Useful for calculating the full calendar months between two dates. 

 

 

timediff

 

 

timediff(period, {time}, {time})

where period one of mis s min h fm fh

This calculation shows the difference between two time fields.  Note this only works with time or date/time fields. 

eg If you want the difference to be shown in minutes it should be;

timediff(min, {time1}, {time2})

If you want the difference shown in hours it would be;

timediff(h, {time1}, {time2})

{time1} and {time2} both have to be time/datetime fields in order for this to work. 

dow

dow({date})

Takes an argument of a date and returns the day of a week as a number 0 to 6.Sunday is 0 through to Saturday which is 6.

if

if(expression,true,false)

This is a logical IF function which evaluates the given expression and returns the true if the condition is met, or false if it is not met. The expression can use fields, logical operators, and keywords. For example:

 The statement if({a}>{b},{a},0) will return field a if a is greater than b, otherwise 0 will be returned.

An if function returning valid will pass validation. Returning invalid will cause the validation message to be shown. For example:

The statement if({a} is {b},invalid,valid) will not pass validation when a is equal to b and the validation message will be shown.

round

round({field},int)

This function will round the given field to the number of specified decimal places. E.g: round(3.4,0)=3 (be sure to set decimal places in the field properties too)

floor
 

ceil

floor({field},int)

ceil({field},int)

This function will round the given field DOWN to the number of specified decimal places. E.g: floor(3.99,0)=3 (be sure to set decimal places in the field properties too)

The related ceil function will round the given field UP to the number of specified decimal places. E.g: ceil(3.99,0)=4 (be sure to set decimal places in the field properties too)

sum

sum({subform/field})

Sums a repeatable field.

min

min({subform/field})

Returns the lowest value entered for a repeatable field.  Only works with integer values.

max

max({subform/field})

Returns the highest value entered for a repeatable field.  Only works with integer values.

contains

contains({array},string)

This function will be true if any one element of the array is equal to the search string.

substr

substr ({field},position,length)

This will return the characters or sub string of a field's value starting at 'position' (the first charater of a string is position=0) and lasting 'length' characters.

substring

substring ({field},start,end)

This will return the characters or sub string of a field's value starting at 'start’' (the first character of a string is position=0) until the character at position (end -1). e.g. substring(“Firmstep”,1,5) will return “irms”

replace/replaceAll

replace({field},{token1},{token2})

replaceAll({field},{token1},{token2})

Further details on replace function

lowerstr

lowerstr({field})

This will convert the string to lowercase. It can be used to remove case sensitivity for validation calculations where input and test fields may be different cases.

E.g. if(lowerstr({input})=lowerstr({output}),valid,invalid)

upperstr

upperstr({field})

This will convert the string to uppercase. It can be used to remove case sensitivity for validation calculations where input and test fields may be different cases.

E.g. if(upperstr({input})=upperstr({output}),valid,invalid)

instr

instr(string1,string2)

Checks whether the first string contains the second. E.g. if(instr({field},'A'),1,0)) returns 1 if {field} contains 'A' and 0 otherwise.

entry

entry({subform/field},1)

Returns the value of a field in a particular row of a subform.

length

length({allfields})

Determines the length of the array evaluated

concat

concat({text1},{text2},{text3})

This function concatenates the arguments being passed, eg becomes text1,text2,text3

using + with differing field types will cause it to try and add instead of concat. Concat is advised for use instead with non-string fields.

trim

trim(string)

This function removes  whitespaces  from the beginning and from the end of the string. e.g.  trim(“  test  “) will convert the string  into “test”

ucfirst

ucfirst({token})

Capitalizes the first character of a given lower case string that does not contain spaces.  (If necessary may need to use lowerstr first)

toCamelCase

toCamelCase({string})

Removes white espaces of the input and capitalize the first letter of each  string contained in the input. e.g. toCamelCase(“test bank statement.pdf”) will return testBankStatement.pdf

fromCamelCase

fromCamelCase({string})

it returns the input to its original format.

toUnderScore

toUnderScore({text1})

It returns the string replacing  whitespaces with underscores. e.g. toUnderScore(“John Smith”) will return 'john_Smith'  Please note the first letter is set to lowercase.  replaceAll can be used instead if you want to maintain the case sensitivity.  For example: replaceAll({text1}," ","_")

fromUnderScore

fromUnderScore({text1})

It returns the string replacing  underscores with whitespaces. e.g.fromUnderScore(“John_ Smith”) will return “John Smith”

startsWith

startsWith({token1},'test')

Determines whether the beginning of the first string  starts with the second argument of the function. e.g.  

startsWith(“Firmstep”,”Fi”) will return true

endsWith

endsWith({token1},'test')

Determines whether the first argument of the function ends with the second string

dateFormat

dateFormat({date1},format)

This function changes the format of a given date. e.g. dateFormat(“21/01/1999”, 'MM-dd-yy') will return 01-21-99
or dateFormat({date1}, 'ddd') does the shorthand day name.  Only works when used with date fields.

timeFormat

timeFormat({time1},format)

This function changes the format of a time field for a given format.  Only works when used with date fields.

getDay

getDay({date1})

This function will return the day of a given date field. e.g. getDay(“11/02/2015”) will return 11.  Only works when used with date fields.  This functionality is currently not available.  Instead use dateFormat.  E.g dateFormat({date1},'dd')

getWeek

getWeek({date1})

It returns the week of a given date. The result for the previous date will be 2.  Only works when used with date fields.  This functionality is currently not available.  

getMonth

getMonth({date1})

It returns the month of a given date

The result for the previous date will be 2.  Only works when used with date fields.  This functionality is currently not available.  Instead use dateFormat.  E.g dateFormat({date1},'MM')

getYear

getYear({date1})

 This functionality is currently not available.  Instead use dateFormat.  E.g dateFormat({date1},'yyyy')

dayofweek

dayofweek({date1})

It returns the day of the week of a given date. The result for the 11/02/2015 will be 4 (Wednesday). Only works when used with date fields.

dayofyear

dayofyear({date1})

It returns the day of the year of a given date.The result for the 11/02/2015 will be 42. Only works when used with date fields.

weekofyear

weekofyear({date1})

It returns the week of the year of a given date.The result for the 11/02//2015 will be  7. Only works when used with date fields.

dayName

dayName({date1})

It returns the day of the year of a given date.The result for the 11/02/2015 will be  Wednesday. Only works when used with date fields.

monthName

monthName({date1})

It returns the month of the year of a given date.The result for the 11/02/2015 will be February. Only works when used with date fields.

isLeapYear

isLeapYear({date1})

It returns whether the year is leap or not.  Only works when used with date fields.


top of page

Common subform Functions

The following functions are commonly used to complete a calculation that references a repeatable subform. To make them more easily found on this page, we have made another table below specifically:

sum sum({subform/field}) Sums a repeatable field.
 min min({subform/field}) Returns the lowest value entered for a repeatable field.  Only works with integer values.
 max max({subform/field}) Returns the highest value entered for a repeatable field
 entry entry({subform/field},1)  Returns the value of a field in a particular row of a subform.
 concat concat({subform/field}) Appends every value entered for a repeatable field into a single string, without a delimiter. You can also just use {subform/field} to get a comma-delimited list, but this isn't always useful if the field can be blank or contain commas

Regex

Regex statements can be used where required to check validity/format of data etc

Note when using regex the product will append /g to the regex which can break some regex statements eg /gim becomes /gim/g which causes the regex to fail

So when using match do not combine with /gim

eg.

upperstr({postcode}) match '^(GIR ?0AA [A-PR-UWYZ]([0-9]{1,2} ([A-HK-Y][0-9]([0-9ABEHMNPRV-Y])?) [0-9][A-HJKPS-UW]) ?[0-9][ABD-HJLNP-UW-Z]{2})$'

This will always check the postcode field as if all characters are upper case.  

Firmstep Validation masks


top of page

Common Solutions

  • All tokens must be shown in a calculation within the curly brackets eg {now}
  • How can I add together the total of the same field from a repeating subform? - Use a calculated field on the main form with the following calculation: sum({subformname/fieldname})
  • How do I get numbers from numerous select one fields to add correctly rather than being concatenated? - The calculation needs to look like this: n({field1})+n({field2})
  • How do I add a day (24 hours) to a date field? - By adding a calculated field to the form with the following calculation: {datefield} + 1 days
    The 'days' statement is not a typo but is the expected syntax. The results of this calculation can then be used in another date field, or within a paragraph, subheading or rich text field to display the result.
  • Can I pull values in from the url? - Yes, you need to set the default value of field to be {querystring:parameter}.  So for example if in the url loading the form you have ?parameter=1 this would populate the field with a default value of {querystring:parameter} with 1. 
  • How can I stop a form being submitted before a large upload has completed its upload? Use count({upload1})  where upload1 is the upload field - to check that the upload has been made and then set a validation calculation  that this must be >0 to prevent the form from submitting without the file upload being completed
  • If a default value is based on a lookup/calculation - then the first time it is filled the result provided clears the default value - so it will not update if moving from one section to another and back - making the field read only will enforce the default value token to be maintained so it will update if you return to the section and make any changes
  • Date calculation that only involves weekdays and ignores weekends - (datediff('d', {date1}, {date2}) - (datediff('fw',{date1},{date2}) * 7) ) + ( datediff('fw',{date1},{date2})*5).
  • Note: if you wish to create a calculation that only involves working days, you will have to create your own lookup that queries a database. Database integrations of this type have been used in the FOI and Contact Us MyServices.(see https://www.gov.uk/bank-holidays.json)
  • Making a select field read only once a selection has been made - add a read only condition of  {select1}<>'' to the advanced tab (note this means the users cannot correct their entry)
  • The default values of read-only fields are evaluated in a different order than other fields. For read-only fields, the default value takes precedence over all other types of value. This is explained in full in our field evaluation guide

  • How to use 'or' and 'and' conditions in a if statement
    When using an 'or'/'and' condition in an if statement it must be within brackets.  'or' is represented as ||, 'and' is represented as &&.  For example;

     if(({text1}='Yes'&&{text2}='Yes'),'Both are Yes','One or both are not Yes')

    In the above, the result will only be 'Both are Yes' when {text1} and {text2} have a value of 'Yes'. 

    For a or condition it would be;

     if(({text1}='Yes'||{text2}='Yes'),'Either are Yes','None are Yes') 
  • Identifying originator name (on any stage)

     if({originator_name}='',{user_name},{originator_name})  
  • Identifying originator email (on any stage)

     if({originator_name}='',{user_email},{originator}) 
  • It is possible to use tokens to enable conditional switching between Submission Redirect URLs as required eg:
    add a hidden field on your form eg {redirectURL}  then set a default value for this field using syntax
    if({selectfield} = 'something','https://weblink','https://weblink2')

 

 

Further useful reading: 

 

top of page

  • Use of double quotes (") rather than single ones (') as string delimiters can cause issues.  For this reason we recommend using only single quotes. 
  • When using calculations based on field tokens within a form, the calculation needs to be after the input fields which are used in the calculation.
  • Using getYear in calculations can cause knock-on issues with other date fields. We recommend putting the getYear call in a separate field, then formatting it to a string when using it in calculations. e.g format({seperateGetYear},string) + 1
  • 'replace' calculation doesn't work when trying to remove a full stop.  For example this wouldn't work 'replace({text2},'.','')' instead you can use custom regex.  For example replace({token},"/\\./g",'') .
  • You are not able to reference repeating values directly in calculations.  If you have a multiple select field for example this creates a comma string when you use the token directly in a calculation which will cause it to fail.  Instead pass the value into a hidden text field first.  Then use this new fields data name in your calculation. 
  • 'Calculation Error: Undefined' message that appears is likely caused by a mistake in the calculation. The only way to resolve this issue is to break down the calculation and carefully check that everything is correct. Two examples could be a misplaced bracket or a special character being in the wrong place.
  • {today} - there are some issues with this token and others may prove more accurate
  • Calculating a task or case due date in the task or case due date fields themselves creates issues. We would recommend doing the date calculation inside the form and then using this token only in the case or task due/warn date fields.

Powered by