Search…
Reference of Ninox scripting functions
We are currently rewriting our product documentation. It isn’t complete yet but growing. An alphabetical overview of the NX script (especially mathematical and date + time) functions is ready for your review. Check it out!
NX, the Ninox query language, is a powerful programming language which allows you to quickly extend Ninox databases with calculations and trigger actions.
While Ninox provides a visual function editor as described in the online manual, it also sports a text-mode for entering more complex expressions. This manual covers the text mode.

## Basic Arithmetics

NX provides arithmetic operations comparable to most other programming languages:
1 + 2 = 33 - 2 = 12 * 3 = 610 / 5 = 2
Arithmetic operations respect the typical operator precedence:
1 + 2 * 3 = 1 + (2 * 3) = 7
Expressions may be enclosed in parentheses:
(1 + 2) * 3 = 9
Note, that NX will automatically remove insignificant parentheses, i. e. if you enter `1 + (2 * 3)` it will store this expression as `1 + 2 * 3`.

## String Operations

A string, i. e. a sequence of characters, may be entered enclosed in double-quotes:
"Hello World!""This is a string."
Strings may be concatenated using the + operator:
"Hello World!" + " " + "This is a string." "Hello World! This is a String."
Strings may also be concatenated with other values:
"Hi " + 42 = "Hi 42"2 + " fast " + 4 + " U" -- "2 fast 4 U"
To enclose a double-quote within a string, it has to be escaped as “”:
"Hi, my name is ""Sally""!"

## Working with Fields

Most NX functions operate in the context of a specific record. NX gives you access to all fields of that record. Consider a table Customer consisting of fields First Name, Last Name, Street, ZIP, City. To generate the full address line, you may enter:
Street + ", " + ZIP + " " + City
Some field names may contain special characters like spaces, dots, colons and so on. Also they may collide with a reserved keyword of NX, like if, then, else. To work around this, field names can be enclosed in single quotes:
'First Name' + " " + 'Last Name'
If a field name contains a single quote, this has to be escapes as '' (two single quotation marks/inverted commas):
'Last year''s total revenue'
Note, that NX is agnostic to field name changes. That is, if you’ve entered an expression referring to a field and you change that field’s name afterwards it will not have an impact to the expression. This is due to the fact that NX internally stores the expression with a reference to the field’s ID (which cannot me modified). Actually, if you open the function editor again, it will reflect the field’s new name.

## Working with Table References

NX expressions can navigate along table references as well. Table references are always one-to-may relationships, e.g. one Customer may have many Invoices — where the table reference is defined as from Invoice to Customer (Invoice => Customer).
To display the Customer’s name in an Invoice, you’d write:
Customer.NameCustomer.'First Name' + " " + Customer.'Last Name'
Expressions may even jump along multiple hops, consider the case where a Customer has a reference to a Company. You could then display the Company’s in the Invoice as well:
Customer.Company.Name
Vice-versa, it’s also possible to get invoice information for a Customer. Remember, that a Customer may have multiple Invoice’s. Thus, an expression referring to the Customer’s invoices will return multiple values. In order to display those values, some kind of aggregation has to be applied. The most common one is to sum up values:
sum(Invoice.Amount)
But there are other aggregations as well:
`avg(Invoice.Amount) ` -- the average, ignoring empty field `cnt(Invoice.Amount) ` -- the count of non-empty fields `min(Invoice.Amount) ` -- the minimum value, ignoring empty fields `max(Invoice.Amount) ` -- the maximum value, ignoring empty fields `first(Invoice.Amount)` -- the first value, according to Ninox' internal sorting `last(Invoice.Amount)` -- the last value, according to Ninox' internal sorting `concat(Invoice.Amount)` -- lists all values, separated by ", "

## Logical Expressions

Logical expressions check if something is the case or not. Most often you’ll need them to create specific filter rules or to make decisions within a calculation. A logical expression either returns true or false. The most common form of a logical expression is a comparison of two values, like:
`Amount > 100` -- greater than `Amount < 100` -- less than Amount >= 100 -- greater than or equal to `Amount <= 100 ` -- less than or equal to `Amount = 100` -- equal `Amount != 100` -- not equal
Logical expressions may be combined by and, or, not.
Age > 12 and Age < 18Status = 1 or Status = 2 or Status = 3not (Status = 4 or Status = 5)Status != 4 and Status != 5
Note, the operator precedence is not -> and -> or.

## Making Decisions

In the previous chapter you’ve learned about logical expressions. The result of such an expression may be used in an if / then / else expression:
if Age < 18 then "Child" else "Grown-up" endif Age < 18 then if Age < 13 then "Child" else "Teenager"else "Grown-up"end
Please note, that the then and else part have to return values of the same data type. You can omit the else clause, which returns a null or no operation (void) for the false portion of an if expression. Terminate the if-block with an end statement.
Use switch case for short specific assignments with a default:
switch <expression> do  case <value>: <result value> case <value2>: <result value2> ...  default: <default value> end
You can use any number of case statements, but their result values must all be the same data type and the optional default statement must be the last option before end, when used. Result values can also contain multiple instructions, such as assignments and calculations, as long as the returned value data types match each other. Ninox will surround multiple instructions in parenthesis to group them together.

## Filtering Values

In the chapter “Working with Table References” you’ve already learned how to access multiple values from a table referring the current one — like `sum(Invoice.Amount)`. With logical expressions, these results may also be filtered. A filter expression has to be enclosed in braces:
sum((Invoice where Status = 2).Amount)sum(Invoice[Status = 2].Amount)
This will only sum up the Invoice Amounts of Invoices with Status = 2.
You may also order by one field while returning another:
`(select Invoice) order by Amount`
This will return the id's of all Invoice records in the ascending order of Amount.
`select Invoice[Status=2] order by Amount`
Same but limiting the returned id's to a status of 2

## Calling Functions

NX provides a range of built-in functions allowing you to transform values. A function call has the form:
`function ( argument1, argument2, … )`
Some examples:
`age(Birthdate)` -- The current age of a person with given Birthdate in years
`cos(5)` -- Cosinus of 5
Creating User defined functions locally with the function command:
`function name(argument:data type,...)  ` `do <script instructions> end`
Note that a custom function can appear anywhere in a script, but they must come before any call to them, including calling another custom function.

## Using Variables

Sometimes it can be useful to store the result of a intermediate calculation and do further calculations based on that result. Consider the case where you want to check the age of a person like:
if age(Birthdate) > 18 then "Grown-up"else if age(Birthdate) > 12 then "Teenager"else "Child"end
Since `age(Birthday)` is used multiple times, things may be simplified with a variable which stores the result of the age calculation:
`let a := age(Birthdate);`
`if a > 18 then "Grown-up" else if a > 12 then "Teenager" else "Child" end`
A variable is declared with a `let` statement:
`let variable := expression;`
Any expression following that let statement can make use of that variable.
`var variable := expression`
These variables can be modified afterwards, such as in loops.
`let x := 1; ...; x := x + 1;` `var y := 1; ...; y := y + 1;`

## Modifying Data

Some expressions in NX may also modify data. Up to the current release 1.5 of Ninox, this is only allowed for trigger expressions (field option Trigger after update). While further enhancements are planned, modifying data is currently restricted to change the value of record fields.
As an example, consider a table Article with a field Price (number) and another table Invoice Item with fields Article (reference to table Article) and Price (number). After assigning the Article, Ninox shall copy the Article’s Price to the Invoice Item’s Price. This can be achieved with a Trigger after update on Article containing following expression:
Price := Article.Price
It is also possible, to update multiple fields, using a semicolon:
Price := Article.Price;Description := Article.'Article No' + " " + Article.Name

## Create Records

With the create statement it’s possible to create new records for a table. The following example creates a new record for the table Person and stores a reference to that record in the variable p. It then assigns a Name to the newly created Person.
let p := create Person;p.Name := "Sarah Conner"
You can also duplicate a record to create a new one. "This" is an automatic handle to the current record.
duplicate(this)

## Select Records

Typically, formulas will access data from related tables like descibed above (“Working with Table References”). However, using the select statement there’s also a way to access data from an unrelated tables.
`select Person`
Will look up all Person records, this statement returns an array of record references.
`select Person where ZIP="10000"`
This statement selects only the Persons with the given ZIP value 10000.
Selecting records is useful in many situations, one common case is to calculate the next Invoice ID.
`'Invoice ID' := max((select Invoices).'Invoice ID') + 1`
Selecting records is useful in many situations, one common case is to calculate the next Invoice ID.
record(tableName, recordId) record(tableName, recordId).fieldName
Use the record function to return the nth record id of a table as a handle. Note that recordID is not a position in a sorted view. If a record has been deleted, using that recordID will return a null, since the ID no longer exists and never will again.

## Delete Records

With the delete command, it’s possible to remove one or more records. Be careful in combination with select, because this may affect a wide range of records with a single call. Some examples:
`delete first(select Person where 'First Name' like "Hans")`
This will look up the first record from the Person table where the name contains "Hans" and remove it.
delete select Person where 'First Name' like "Hans"
This will look up the all records from the Person table where the name contains "Hans" and remove all matching records.
`delete select Person`
Will remove any record in the person table.
`delete Customer`
When issued on an invoice record, this will remove the customer that is linked to the current invoice.
`delete Invoices`
When issued on a customer record, this will remove all invoices which are linked to the current customer.

## Loops

The for statement can be used to loop over arrays of values – e.g. the result of a select.
for p in (select Person)p.Haircolor := "red"
This exmple would lookup all Person records (select Person). For each record (stored in the variable p) it would then change the Person‘s Haircolor to red.
Use the `range(From, To)` function to create counting loops:
for i in range(0, 10) do ... end
Please note, that for range(From, To), From in inclusive and To is exclusive. To state an example:
concat(range(0, 4))=> 0, 1, 2, 3concat(for i in range(0, 4) do i*i end) => 0, 1, 4, 9
Similar to in range:
for i from <start> to <end> do ... end for i from <start> to <end> step <step> do ... end
While loops test the condition at the beginning
while <expression is true> do ... end

## Arrays

Some expressions will return arrays, that is lists of values, as a result. E. g. the reverse end of a relation will return an array of record ids:
Costumer.Invoices => [ID1, ID2, ID3]
It is also possible to create an array explicitly with the following syntax:
let MyArray1 := [1, 2, 81];let MyArray2 := [1, 2, 9 * 9];

### Function Reference

Type Conversion
Number Functions
number(value)
Tries to interpret the given value as a number.
• If value stems from a choice field, this will be the choice’s internal id. Use number(text(choice)) to get a numeric representation of the choice’s text.
• If value is a date, time or timestamp, this will be the the number of milliseconds between midnight of January 1, 1970 and the specified date.
• If value is an appointment, it is treated like the appointment’s begin date.
`| number("10")` => 10 `| number(5)` => 5 `number(now())` => 1531402014168

## Mathematical Functions

`round(x)` – Rounds a number to the nearest integer. `round(x, digits)` – Rounds a number with the given amount of digits. `| round(1.234, 2)` => 1.23 `| round(12345.987, -2)` => 12300
`floor(x)` – Rounds a number DOWNWARDS to the nearest integer.
`ceil(x)` – Rounds a number UPWARDS to the nearest integer.
`sqrt(x) `– the square root of x.
`sqr(x)` – the square of x => x2
`sign(x) `– the signum of x: `| sign(-2.5)` => -1 `| sign(2.5)` => 1 `| sign(0)` => 1
`abs(x) `– the absolute value of x `| abs(-5) = abs(5) = 5`
`sin(x) `– Sinus of x (in radians)
`cos(x) `– Cosinus of x (in radians)
`tan(x)` – Tangens of x (in radians)
`asin(x) `– Arcus sinus of x (in radians)
`acos(x) `– Arcus cosinus of x (in radians)
`atan(x) `– Arcus tangens of x (in radians)
`atan2(x,y) `– Arcus tangens of x/y (in radians), squared
`degrees(x)` – Converts angle x from radians to degrees
`radians(x)` – Converts angle x from degrees to radians
`random() `– A random number between 0 (incl.) and 1 (excl.)
`pow(x, y) `– x to the power of y: xy
`exp(x) `– x to the power of e => ex
`log(x) `– Logarithm of x to the base of 10.
`log(x, y) `– Logarithm of x to the base of y
`ln(x) `– Natural logarithm of x
`odd(number) `– true, if number is odd
`even(number) `– true, if a number is even

## Text Functions

text(value)
Converts any value to a string representation possibly reflecting the format option of its field settings. If there’s no value, the result will be the empty string: "".
`| text("Hello")` => "Hello" `| text(2.34) `=> "2.34" `| text(MyCurrencyField)` => "1,234.56 quot; `| text(today())` => "07/13/2018"
`length(string)` – Returns the string’s length (the number of characters)
`trim(string)` – Removes leading and trailing white-space of string
`lower(string)` – Converts a string to lower case
`upper(string)` – Converts a string to upper case
`lpad(string, length, padding) - `If the string’s length is smaller than the given length, the missing space is filled up with the given padding at the start of the string.
`rpad(string, length, padding)` - If the string’s length is smaller than the given length, the missing space is filled up with the given padding at the end of the string.
`substring(string, start, end)` – Extracts a part of the string. Start and end are zero-based. `| substring("Hello World!", 0, 5)` => "Hello" `| substring("Hello World!", 6, 11)` => "World"
`substr(string, start, length)` – Extracts a part of the string. Start is zero-based. `| substr("Hello World!", 0, 5)` => "Hello" `| substr("Hello World!", 6, 5)` => "World"
`substr(string, start)` – Extracts a part of the string. Start is zero-based. `| substr("Hello World!", 4)` => "o World!"
`contains(string, match)` – Checks if string contains the given match string by exact comparison. `| contains("Hello World!", "World")` => true `| contains("Hello World!", "world")` => false
An alternative way to check if a string contains a match string is the keyword `like. Note that the order of the checked strings is important.`
`| "Hello" like "el" => true` `| "el" like "Hello" => false`
`index(string, match)` – Finds the start index of the given match string within string. `| index("Hello World!", "World")` => 6 `| index("Hello World!", "world")` => -1 (not found)
`replace(string, find, replace)` – Replaces any occurance of find with replace. `| replace("Hello World", "l", "X")` => "HeXXo WorXd"
`replacex(string, pattern, flags, replace)` – Replaces occurrences of pattern in string with replace. Pattern is a regular expression string; flags is an optional string specifying how the match takes place. Replace is a string, optionally using argument expressions. This call is compatible to JavaScript’s string.
`replace(new RegExp(pattern, flags), replace)` `| replacex("Hello World", "l", "g", "X")` => "HeXXo WorXd"
`testx(string, regular_expression, flags) - `boolean
`testx(string, regular_expression) - `boolean
`extractx(string, regular_expression, flags, extract) ` `extractx(string, regular_expression, extract)` `extractx(string, regular_expression)`
extracts a substring from the given string
`capitalize(string) - `Capitalizes the first letter of each word
`styled(text, bgcolor, fontcolor, icon) -` creates styled text elements. The icon is placed to the left of the text. The first color represents the background color and the second one the font color. Use `""` for none, and the color is the object's background `| styled("Attention", "yellow", "red", "warn")`
There are also shorter versions of the `styled` function, in which the font color will be automatically contrasting the background color:
`styled(text, bgcolor)`
`styled(text, bgcolor, icon) `
`format(number, format mask) -` Converts a number into formatted text. Format mask elements:
- 0 represents a number or 0 - # represents a number that is displayed only, if the number is big enough - period (.) represents the decimal separator (will be formatted according to the country, that means, in the UK and US it is shown as a floating point) - comma (,) represents the grouping separator (will be formatted according to the country, that means, in the UK and US it is shown as a comma)
Examples: `| format(42.5, "0")` => "42"  `| format(42.5, "000")` => "042"  `| format(42.5, "000.00")` => "042.50"  `| format(42.5, "0.00")` => "42.50"  `| format(42.5, "#,##0.00")` => "42.50"  `| format(1042.5, "#,##0.00")` => "1,042.50"

## JSON Data

`formatJSON(jsonObject)` - creates a JSON string of a valid JSON object `parseJSON(jsonString)` - reconstructs a JSON object from a valid JSON string. In case of an invalid string, the function returns undefined.

## Arrays

`array(array1, array2) ` - creates a new array by merging two arrays of similar type
`sort(array) ` - sorts an array in ascending order `rsort(array)` - sorts an array in descending order
`item(array, index) - `extracts a single item of an array, the index is zero based
`slice(array, start, end)` - extracts a sub-array. Start is zero based and both are position numbers.
`sum(array) ` `avg(array) ` `first(array) ` `last(array) ` `min(array) ` `max(array) ` `cnt(array) or count(array) `
Aggregates array items from an array and returns a single result
`concat(array)` - Returns a string result with ", " (comma space) separating each element `join(array,"separator")` - Returns a string result with each element separated by a separator of your choice. That can also be a line break and/or a string.
`unique(array)` - returns unique values of the array as an array `unique("item1","item2","item1","item3","item2")` => ["item1","item2","item3"]
`range(start, end) ` `range(start, end, step)` Returns an array of consecutive numbers from start to one minus end, by an optional step value or one. Start can be higher than end, in which case they're numbered in reverse order.
`range(end)` - is the same as range(0, end)
`split(string, separator) ` - Split a string into an array at each separator `splitx(string, regular expresion)` - Split a string into an array by using a regular expression `| split("Hello World", " ")` => ["Hello", "World"]  `| splitx("Hello World", "\s")` => ["Hello", "World"]
`chosen(field)` - Get all chosen values from a multiple choice field `chosen('multi choice field')` => ["Option 1", "Option 2"]
`chosen('multi choice field', number)` - Returns true if the given number equals the ID of a selected choice value
`chosen('multi choice field', [number])` - Returns true if the numbers of the given array equal the IDs of a selected choice values
`chosen('multi choice field', string)` - Returns true if the given string equals a selected choice
`numbers('multi choice field')` - returns the value IDs of the selected values in a multiple choice field
`numbers('multi choice field (dynamic)')` - returns the record IDs of the selected values in a dynamic multiple choice field

## Date Functions

`date(year, month, day)` – Returns a date value `| date(2018, 6, 15)` => 15.06.2018
`date(number)` – Converts a number to a date value. The number represents the number of milliseconds since the UNIX epoch ( 00:00:00 UTC on 1 January 1970)
`date(datetime)` – Converts a timestamp data type to a date value (leaving out the time value).
`year(date)` – Full year of the given date `year(datetime)` – Full year of the given date+time value `year(appointment)` – Full year of the start date of an given appointment.
`year(number)` - Converts a number to a date value and returns the year of the date.
`month(date)` – Month of the given date (1 = January, … 12 = December) `month(datetime)` – Month of the given timestamp `month(appointment)` – Month of the start date of a given appointment
`month(number)` – Converts a number to a date value and returns the month of the date. `monthName(number)` – Name of the given month number `| monthName(1) `=> “January”
`monthName(date)` – Name of the month of a given date `monthIndex(text)` – Number of the given month name `| monthIndex(“January”) `=> 1
`day(date) `– Day of month of the given date (between 1 and 31) `day(datetime) `– Day of month of the given date+time value `day(appointment)` – Day of month of the start date of the given appointment
`day(number)` – Converts a number to a date value and returns the day of the date.
`weekday(date)` – Weekday of the given date (0 = Monday, 1 = Tuesday, … 6 = Sunday) `weekday(datetime)` – Weekday of the given date+time value `weekday(appointment)` – Weekday of the start date of the given appointment `weekdayName(number) `– Name of the given weekday number `| weekdayName(6) `=> “Sunday”
`weekdayName(date)` – Name of the weekday of a given date
`weekdayName(appointment)` – Name of the weekday of a given appointment's start date `weekdayIndex(text)` – Number value of the given weekday name `| weekdayIndex(“Sunday”) `=> 6
`today()` – the current date (without time)
`now()` – the current timestamp
`age(date)` – Number of full year’s between now and the given date (e.g. a person’s age)
`format(date, format)` `format(datetime, format)` `format(appointment, format)` `| format(timefield, "hh:mm")` => "10:30" `| format(datetime, "DD.MM.YYYY, hh:mm")` => "13.11.2018, 16:45"
Formats a date as a string. The format expression is a string which may contain following tokens (example for 15th of July 2018, 01:02:03 am):
Token
Description
Example
YY
two digit year
18
YYYY
four digit year
2018
M
one or two digit month
6
Mo
month ordinal
6th
MM
two digit month
6
MMM
three character month name
Jun
MMMM
full month name
June
D
one or two digit day
15
Do
ordinal day
15th
DD
two digit day
15
d
day of week as number (0-6)
6
do
ordinal day of week
6th
dd
three character weekday name
Fri
ddd
three character weekday name
Fri.
dddd
full weekday name
Friday
e or E
seems to be same as “d”
6
l
lowercase “L” - M/D/YYYY
6/15/2018
L
MM/DD/YYYY
06/15/2018
w or W
week number of year
24
Q
quarter of year
2
yearmonth(date)yearmonth(datetime)yearmonth(appointment)
Year and month of a date as a string, e.g. "2018/08". Useful for grouping records per month.
yearquarter(date)yearquarter(datetime)yearquarter(appointment)
Year and quarter of a date as a string, e.g. "2018/03". Useful for grouping records per quarter.
In case you just need the quarter number you can use the function `quarter()` with the same parameters.
yearweek(date)yearweek(datetime)yearweek(appointment)
Year and week of year of a date as a string, e.g. "2018/32". Useful for grouping records per calendar week.
week(date) week(datetime) week(appointment)
Calendar week of a date as a number.
`start(appointment)` – Start timestamp of an appointment.
`endof(appointment)` – End timestamp of an appointment.
`duration(appointment)` – Duration of an appointment in milliseconds.
`days(start, end)` – Number of days between two dates.
`workdays(start, end)` – Number of working days between two dates. This function does consider any Monday to Friday to be working days, it does not respect holidays.
`time() `– Returns the current time
`time(number)` – converts a number value (milliseconds) to a time value.
time(hours, minutes)time(hours, minutes, seconds)time(hours, minutes, seconds, millis)
Returns a time value with given hours, minutes, seconds and milliseconds.
datetime(year, month, day)datetime(year, month, day, hour)datetime(year, month, day, hour, minute)datetime(year, month, day, hour, minute, second)datetime(year, month, day, hour, minute, second, millis)
Returns a timestamp value with given year, month, date, hour, minute, second and millisecond.
`datetime(date)` – converts a date value to a date+time value, time is set to 00:00.
`datetime(date, time)` – converts a date and a time value to a timestamp value.
`datetime(number)` – converts a number value,representing the number of milliseconds since the UNIX epoch, to a timestamp data type.
`_cd` - returns the creation timestamp of the current record. Doesn’t appear to work in the Mac app.
`_md` - returns the modification timestamp of the current record. Doesn’t appear to work consistently in the Mac app.
`timeinterval(number)` – converts a number (milliseconds) to a timeinterval value.
`timeinterval(time)` – converts a time value to a timeinterval value.
`appointment(timestamp, timestamp)` - converts timestamp data type to an appointment data type
`appointment(timestamp, duration)` - combines a timestamp and a duration data type into an appointment data type. `duration` could be of type timestamp, time or number
Create specific calendar events: `createCalendarEvent(calendar, title, from, to) ` `createCalendarEvent(calendar, title, appointment) ` `createCalendarEvent(title, from, to) ` `createCalendarEvent(title, appointment) ` `createCalendarEvent(calendar, title, from, to) `
`createCalendarEvent(calendarName, title, from, to)` - Create a calendar event in Apple's Calendar app
`createCalendarReminder(calendar, title, start, due) ` `createCalendarReminder(calendar, title, start) ` `createCalendarReminder(calendar, title) ` `createCalendarReminder(title, start, due) ` `createCalendarReminder(title, start) ` `createCalendarReminder(title)`
`createCalendarReminder(calendarName, title, from, to)` - Create a calendar event in Apple's Reminder app

## Color Functions

`color(text)` – converts a text to a color value `| color("red")` `| color("#f00")` `| color("ff0000")` `| color("rgb(255,0,0)")`
`color` accepts any valid HTML/CSS color identifier.
`color(red, green, blue)` – creates a color value from rgb-components. red, green and blue a numbers between 0 and 255.
`color(red, green, blue, alpha)` – creates a color value from rgb- and alpha-components. red, green and blue a numbers between 0 and 255, alpha is between 0 and 1.
`color(choice)` – returns the color of a choice value.

## Icon Functions

`icon(name)` – returns an icon, e.g. icon(“warn”)
`icon(choice)` – returns the icon of a choice value
A full list of all icons and its corresponding names can be found here in our Ninos Icon-set database.

## Location Functions

`longitude(Location)` – the longitude value of a location field
`latitude(Location)` – the latitude value of a location field
`location(title, latitude, longitude)` – creates a location value with given `title (text)`, `latitude (number)` and `longitude (number)`.

## User Interface Automation

User interface automation has been added with Ninox 1.7.0. It’s not yet available for Ninox Server and Cloud.
`printRecord(recordId, layoutName) - `Creates a PDF from the given record and print layout name. `| printRecord(record(Invoices, 1), "My Invoice Template")`
`openPrintLayout(recordId, layoutName)` - opens the print layout editor `| openPrintLayout(record(Invoices, 1), "My Invoice Template")`
`openRecord(recordId) `- opens the record and jumps to the related table `| openRecord(record(Invoices, 1))`
`openRecord(recordId, tabName) - `opens the record, jumps to the related table and opens the given tab `| openRecord(record(Invoices, 1), "More Details")`
`popupRecord(recordId) `- opens the record in a pop-up form without switching to another table `| popupRecord(record(Invoices, 1))`
`popupRecord(recordId, tabName) - `opens the record in a pop-up form without switching to another table and opens the given tab `| popupRecord(record(Invoices, 1), "More Details")`
`openTable(tableName) - `opens a table
`openTable(tableName, viewName) - `opens a table view `| openTable("Invoices", "All Invoices")`
`printTable(tableName, viewName) - `creates a PDF from the given table view
`closeRecord()` - closes the top-most record form
`closeAllRecords() - `closes all record forms
`alert(string)` - Pops up a message box with an "OK" button. This requester only appears after the script is completed, and with the latest message assigned before the script ended. `| alert("Hello Ninox User!") `
`openFullscreen(recordId) - `opens a record in full-screen mode
`openFullscreen(recordId, tabName) - `opens a given tab of record in full-screen mode
`closeFullscreen() - `closes full-screen mode

## User Management Functions

Please note that the following functions do only work for Ninox Server and Cloud installations. They won’t return useful results for Ninox App.
`user()` – returns the current user value
`user(string) -` returns user if the string is a user's name
`userId(id)` – returns the user value with given id
`userId()` – returns the id of the current user.
`userId(user)` – returns the id of the given user value.
`userName()` – returns the name of the current user.
`userName(user)` – returns the name of the given user value.
`userFirstName()` – first name of the current user
`userFirstName(user)` – first name of the given user value
`userLastName()` – last name of the current user
`userLastName(user)` – last name of the given user value
`userFullName()` – full name of the current user
`userFullName(user)` – full name of the given user value
`userEmail()` – email address of the current user
`userEmail(user)` – email address of the given user value
`userHasRole(string)` – returns true, if the current user has the specified role
`userHasRole(user, string)` – returns true, if a specific user has the specified role
`userRole()` - Get the role of the current user
`userRoles()` - Get all roles of the current user
`userRole(user)` – Get a user's role: string
`userRoles(user)` – Get all roles of a user: string
`users()` – an array of all users: [user]

## Functions to send e-mails **

sendEmail({from: "[email protected]",to: "[email protected]",subject: "Hello World!",text: "Some text",html: "<h1>Some Text</h1><i>With Markup</i>"})

## Importing functions

importFile(this, "https://static.ninoxdb.de/images/[email protected]")
- import a file from an URL and save it as an attachment of a data record
importFile(this, printAndSaveRecord(this, "My Print Layout"), "mypdf.pdf")
- export one of your print layouts as PDF and save it as an attachment of the data record

## Other Functions

`alert("This is the alert message")` - will show a message/an alert with the message "This is the alert message"
`barcodeScan()` - activate the bar code scanner
`dialog("Title", "Message", ["Option A", "Option B"])` - opens a dialog for the user
| ` let result := dialog("Title", "Message", ["Option A", "Option B"]);` ` if result = "Option A" then` ` alert("Good choice")` ` else alert("Great")` ` end`
`do as server <script> end` - Ensure server-side execution of script
`files(this)` - shows all the attachments of a record, please be aware that the function gives an array. Use an additional function like concat(), first(), last() etc.
`file(this, "mypdf.pdf")` - gives a specific file
`html(text)` - Returns a rich text representation of a text.
`http(method, url, header, body)` - Calls REST services . `method` and `url` are strings, `header` and `body` are optional objects.
`ninoxApp()` - returns one of "android-phone" | "android-tablet" | "ipad" | "iphone" | "mac" | "web", identifying the type of app
`openURL(string)` - opens the browser with a given string converted to a URL
`openURL(link)` - opens the browser with a given link
`raw(value)` – returns the internal / raw representation of a value as a text
`urlEncode(string)` - adds percent encodings to a string
`urlDecode(string)` - removes percent encoding from a string
`urlOf(record) - `will generate a link for the given record
`urlOf(record, string, string) - `will generate a link for the specified tab in the specified view of the current table. The first string is the view name, the second one the tab name.
`urlOf(string, string) - `will generate a link for the specified view in the specified table. The first string is the table name, the second one the view name.
`formatXML(object)` - converts a JSON object into XML text
`formatXML(object, boolean)` - converts a JSON object into XML text and can be depicted as structured text if the boolean is true
`parseXML(string)` - converts a XML text to a JSON object
`createTextFile(this, "Hello World", "hello.txt")`
`isDatabaseProtected() - `Returns true if the database is protected
`isDatabaseLocked() - `Returns true if the database is locked
`isAdminMode() - `Returns true if Admin Mode is on
`sleep(number)` - forces Ninox to wait for a given amount of milliseconds
`clientLang()` - returns the language currently being used
`teamId()` - returns ID of the current team
`databaseId()` - returns ID of the current database
`tableId(record)` - returns table ID of a record
`tableId(string)` - returns table ID via a given table name
_________
** (only available in Ninox Cloud/Ninox Server teams)