Natywny JS
Natywny JS pozwala wykonywać kod JavaScript wewnątrz skryptu Ninox oraz dzielić z nim funkcje i zmienne. Dzięki temu natywny JS ma dostęp do zmiennych Ninox i może wywoływać zarówno funkcje lokalne, jak i globalne.

Ograniczenia
Zmiana zmiennej Ninox w natywnym JS nie wpływa na tę zmienną w Ninox.
JavaScript wykonuje się wyłącznie lokalnie. Dodanie JavaScriptu do kodu uruchamianego na serwerze nie daje żadnego efektu. Podobnie wywołanie funkcji globalnej zawierającej JavaScript z kodu wykonywanego na serwerze nie daje żadnego efektu.
Tutaj widać, które fragmenty kodu wykonują się lokalnie, a które na serwerze:

Składnia
Wykonanie
Aby wskazać Ninox, że przechodzą Państwo na JavaScript, należy zamknąć kod w #{ ... }#:
#{ alert("hello world") }#;
Proszę pamiętać, że Ninox jest językiem prekompilowanym, który musi z góry znać typ każdej zmiennej i funkcji. To samo dotyczy natywnego JS: trzeba określić typ zwracany przez kod JavaScript. Domyślnie natywny JS zwraca tekst, ale mogą Państwo wskazać typ zwracanej zmiennej, podając go na samym początku kodu w notacji :[typ].
Wartość zwracana
#{:text return "hello world"}#;
Możliwe typy są takie same jak przy wywołaniach funkcji: text, number, date, datetime, time, timeinterval, appointment, boolean, html, color, icon, email, phone, location, file, user oraz any.
Typy tablicowe
Aby zwrócić tablicę, należy użyć następującej składni:
#{:number(array) return [1,2,3] }#;
Typy rekordowe
Aby zwrócić rekordy, należy użyć nazwy tabeli, po której następuje nid lub rid:
Jeśli używają Państwo nid, trzeba zwrócić tablicę wartości tekstowych zawierających pełny identyfikator rekordu, czyli identyfikator tabeli + numer rekordu:
#{:nid(customer) return ['A1','A2','A3'] }#
Jeśli używają Państwo rid, należy zwrócić numer rekordu:
#{:rid(customer) return [1,2,3] }#
W przypadku nazw tabel złożonych z kilku słów nie należy dodawać ‘ jak w Ninox, lecz po prostu użyć pełnej nazwy tabeli:
#{:rid(my long name table) return [1,2,3] }#
Dzięki tej składni natywny JS zwraca zmienne, które zachowują się tak samo jak w kodzie Ninox. Oznacza to, że można używać poniższej składni tak, jakby to był select:
(#{:rid(customer) return [1,2,3] }# order by 'Last Name').'First Name';

Modyfikacja rekordu
Zmienne typu rekordowego są przekazywane w formacie JSON, z parą klucz-wartość dla każdego pola rekordu.
var r := first(select Customer);
#{:text return r['First Name'] }#;
Zawartość zmiennej r w JavaScripcie wygląda tutaj następująco:
{
"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"
}
Ważne
W zależności od tego, czy kod wykonuje się w aplikacji na Maca, czy w przeglądarce, ID może mieć różną wielkość liter.
Aby temu zaradzić i uniknąć konfliktów między platformami, ID jest powtarzane we wszystkich możliwych wariantach wielkości liter.
Modyfikacja rekordu w JavaScripcie nie aktualizuje go w Ninox.
Wykonanie asynchroniczne
Czasem przydaje się zsynchronizowanie wykonania kodu Ninox z JavaScriptem.
Na przykład przy użyciu timera ważne jest, aby kod zakończył się dopiero po zakończeniu działania timera.
Bez takiej synchronizacji kod następujący po wykonaniu JavaScriptu uruchomiłby się natychmiast, co mogłoby prowadzić do nieoczekiwanych zachowań.
W pierwszym przypadku wartość „I don't know” zwracana jest natychmiast, a funkcja alert wyświetla wynik zanim pytanie zostanie w ogóle zadane użytkownikowi.
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 );

Po przejściu w tryb callback funkcja alert Ninox wykonuje się dopiero po wywołaniu przez kod JavaScript funkcji zwrotnej, czyli po zadaniu pytania użytkownikowi.
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 );

Wywołanie funkcji
Z poziomu JavaScriptu można wywoływać funkcje Ninox. Procedura może być lokalna lub globalna; wystarczy, że znajduje się w zasięgu kodu JavaScript.
function display( message : text ) do
alert( message );
end;
#{ display('hello world') }#;

Aby odebrać wartość zwracaną przez funkcję, trzeba ponownie użyć trybu callback (patrz wyżej: Wykonanie asynchroniczne):
function add( a : number, b : number ) do
a + b;
end;
#{:number:callback
add( 1, 2, (returnValue) => {
callback( returnValue )
})
}#;

Jeśli po wywołaniu procedury nie mają Państwo nic więcej do przetworzenia, można przekazać funkcję zwrotną bezpośrednio jako parametr:
function add( a : number, b : number ) do
a + b;
end;
#{:number:callback
add( 1, 2, callback )
}#;

Operowanie na rekordach i funkcjach
Jeśli mają Państwo listę identyfikatorów rekordów, mogą Państwo wywołać funkcję Ninox, aby zmodyfikować kolejno każdy rekord. Wystarczy wywołać funkcję i przekazać jej identyfikator.
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;
Błędy wykonania
Jeśli w kodzie wystąpi błąd wykonania, zwrócony zostanie tekst komunikatu o błędzie:

