Native JS
Native JS позволяет выполнять код JavaScript внутри скрипта Ninox и обмениваться с ним функциями и переменными. Благодаря этому Native JS может обращаться к переменным Ninox и вызывать как локальные, так и глобальные функции.

Ограничения
Изменение переменной Ninox в NativeJS не затрагивает саму переменную Ninox.
JavaScript выполняется только локально. Добавление JavaScript в код, выполняемый на сервере, не даёт никакого эффекта. Точно так же не даёт эффекта вызов глобальной функции с JavaScript из кода, выполняемого на сервере.
Здесь показано, какие коды выполняются локально, а какие на сервере:

Синтаксис
Выполнение
Чтобы указать Ninox, что вы переходите на JavaScript, заключите код в #{ ... }#:
#{ alert("hello world") }#;
Помните: Ninox — предварительно компилируемый язык, которому нужно заранее знать тип каждой переменной и функции. То же относится и к Native JS: вы должны указать тип, возвращаемый кодом JavaScript. По умолчанию Native JS возвращает текст, но нужный тип можно задать в самом начале кода записью :[type]:
Возвращаемое значение
#{:text return "hello world"}#;
Возможны те же типы, что и при объявлении функций: text, number, date, datetime, time, timeinterval, appointment, boolean, html, color, icon, email, phone, location, file, user и any.
Типы массивов
Чтобы вернуть массив, используйте такой синтаксис:
#{:number(array) return [1,2,3] }#;
Типы записей
Чтобы вернуть записи, укажите имя таблицы, а за ним nid или rid:
Если вы используете nid, нужно вернуть массив текстовых значений с полным идентификатором записи, то есть идентификатором таблицы + номером записи:
#{:nid(customer) return ['A1','A2','A3'] }#
Если вы используете rid, следует вернуть номер записи:
#{:rid(customer) return [1,2,3] }#
Для составных имён таблиц не добавляйте ‘, как в Ninox, а просто пишите полное имя таблицы:
#{:rid(my long name table) return [1,2,3] }#
При таком синтаксисе Native JS возвращает переменные, которые ведут себя так же, как в коде Ninox. Значит, можно писать так, будто это select:
(#{:rid(customer) return [1,2,3] }# order by 'Last Name').'First Name';

Изменение записи
Переменные типа «запись» передаются в формате JSON, где каждому полю записи соответствует пара ключ-значение.
var r := first(select Customer);
#{:text return r['First Name'] }#;
Здесь содержимое переменной r в JavaScript выглядит так:
{
"Created on": 1648910817206,
"Id": "A1",
"Last modified": 1714817525840,
"Modified by": "7zBqhAKXxfQAPmH7Y",
"First Name": "Sofia",
"Last Name": "Young",
"Company": "Kollwitz GmbH",
"Postal Code": "12345",
"City": "New Jersey",
"Address": "11,South Commerce Street",
"Email": "sofi@kollwitz-gmbh.com",
"Customer No": "K0001",
"Title": "2",
"Invoices": [
1,
16,
17
],
"Photo": "shutterstock_307218608.jpg",
"Category": "1",
"Position": "Marketing head",
"Checked": true,
"ID": "A1",
"id": "A1"
}
Важно
В зависимости от того, выполняется ли код в приложении для Mac или в вебе, регистр ID может отличаться.
Чтобы учесть это и избежать расхождений между платформами, ID повторяется во всех возможных вариантах написания.
Изменение записи в JavaScript не обновляет её в Ninox.
Асинхронное выполнение
Иногда бывает нужно согласовать выполнение кода Ninox с JavaScript.
Например, при работе с таймером важно, чтобы код завершался только после того, как таймер отработает.
Без такого согласования код, следующий за выполнением JavaScript, отработает сразу же, что может привести к неожиданному поведению.
В первом случае значение «I don’t know» возвращается немедленно, и функция alert показывает результат раньше, чем вопрос будет задан пользователю.
var r:= #{:text
setTimeout( () => {
if (confirm("Are you ok ?"))
return "of course";
else
return "Never !";
}, 2000);
return "I don't know";
}#;
alert( "Your answer is : "+r );

Если перейти в режим callback, функция alert в Ninox выполнится только после того, как код JavaScript вызовет функцию обратного вызова, то есть после того, как вопрос будет задан пользователю.
var r:= #{:text:callback
setTimeout( () => {
if (confirm("Are you ok ?"))
callback( "of course" );
else
callback( "Never !" );
}, 2000);
return "I don't know";
}#;
alert( "Your answer is : "+r );

Вызов функции
Из JavaScript можно вызывать функции Ninox. Процедура может быть локальной или глобальной — важно лишь, чтобы она находилась в области видимости кода JavaScript.
function display( message : text ) do
alert( message );
end;
#{ display('hello world') }#;

Чтобы получить возвращаемое значение функции, снова понадобится режим callback (см. выше: Асинхронное выполнение):
function add( a : number, b : number ) do
a + b;
end;
#{:number:callback
add( 1, 2, (returnValue) => {
callback( returnValue )
})
}#;

Если после вызова процедуры никакой дальнейшей обработки не требуется, функцию обратного вызова можно передать параметром напрямую:
function add( a : number, b : number ) do
a + b;
end;
#{:number:callback
add( 1, 2, callback )
}#;

Работа с записями и функциями
Если у вас есть список идентификаторов записей, можно вызвать функцию Ninox, чтобы изменить каждую запись по очереди. Для этого достаточно вызвать функцию и передать ей идентификатор.
function setCustomerChecked( id : text, checked : boolean ) do
var n := number(replacex(id, "\D",""));
var rec := record( Customer, n );
rec.Checked := checked;
end;
var c := select Customer;
var isChecked := not first(c).Checked;
#{
c.forEach( v => { setCustomerChecked( v, isChecked ) } );
}#;
c.checked;
Ошибки выполнения
Если в коде происходит ошибка выполнения, возвращается текст сообщения об ошибке:

