JS nativo
Native JS permette di eseguire codice JavaScript all'interno di uno script Ninox e di condividere con esso funzioni e variabili. In questo modo Native JS può accedere alle variabili Ninox e chiamare funzioni sia locali sia globali.

Limiti
Modificare una variabile Ninox in NativeJS non ha effetto sulla variabile Ninox.
Il JavaScript viene eseguito solo in locale. Aggiungere JavaScript a codice che gira sul server non ha alcun effetto. Allo stesso modo, chiamare una funzione globale che contiene JavaScript da codice eseguito sul server non ha alcun effetto.
Qui sotto trovate quali codici vengono eseguiti in locale e quali sul server :

Sintassi
Esecuzione
Per indicare a Ninox che si passa a JavaScript, occorre racchiudere il codice tra #{ ... }#.:
#{ alert("hello world") }#;
Ricordate che Ninox è un linguaggio precompilato, che deve conoscere in anticipo il tipo di ogni variabile e di ogni funzione. Lo stesso vale per Native JS: dovete indicare il tipo restituito dal codice JavaScript. Per impostazione predefinita Native JS restituisce del testo, ma potete indicare il tipo di variabile da restituire specificandolo all'inizio del codice con la notazione :[type]. :
Valore restituito
#{:text return "hello world"}#;
I tipi possibili sono gli stessi usati per le chiamate di funzione: text, number, date, datetime, time, timeinterval, appointment, boolean, html, color, icon, email, phone, location, file, user e any.
Tipi array
Per restituire un array, usate la sintassi seguente :
#{:number(array) return [1,2,3] }#;
Tipi record
Per restituire dei record, usate il nome della tabella seguito da nid o rid:
Se usate nid, dovete restituire un array di valori di testo contenenti l'identificatore completo del record, cioè l'identificatore della tabella + il numero del record:
#{:nid(customer) return ['A1','A2','A3'] }#
Se usate rid, dovete restituire il numero del record :
#{:rid(customer) return [1,2,3] }#
Per i nomi di tabella composti, non aggiungete ‘ come in Ninox, ma usate semplicemente il nome completo della tabella :
#{:rid(my long name table) return [1,2,3] }#
Con questa sintassi, Native JS restituisce variabili che si comportano come nel codice Ninox. Significa che potete usare la sintassi seguente come se fosse un select :
(#{:rid(customer) return [1,2,3] }# order by 'Last Name').'First Name';

Modifica di un record
Le variabili di tipo record vengono passate in formato JSON, con una coppia chiave-valore per ogni campo del record.
var r := first(select Customer);
#{:text return r['First Name'] }#;
Qui il contenuto della variabile r in JavaScript si presenta così :
{
"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"
}
Importante
A seconda che il codice venga eseguito sull'applicazione Mac o sul web, l'ID può avere maiuscole e minuscole diverse.
Per ovviare a questo ed evitare conflitti tra piattaforme diverse, l'ID è ripetuto in tutte le varianti possibili di maiuscole e minuscole.
Modificare il record in JavaScript non lo aggiorna in Ninox.
Esecuzione asincrona
A volte è utile sincronizzare l'esecuzione del codice Ninox con il JavaScript.
Per esempio, quando si usa un timer, è importante che il codice si concluda solo dopo che il timer ha terminato l'esecuzione.
Senza questa sincronizzazione, il codice che segue l'esecuzione JavaScript verrebbe eseguito immediatamente, con possibili comportamenti inattesi.
In questo primo caso il valore «I don't know» viene restituito subito e la funzione alert mostra il risultato prima ancora che la domanda venga presentata all'utente.
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 );

Passando alla modalità callback, la funzione alert di Ninox viene eseguita solo dopo che il codice JavaScript ha chiamato la funzione di callback, cioè dopo che la domanda è stata presentata all'utente.
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 );

Chiamata di funzione
È possibile chiamare funzioni Ninox dal JavaScript. La procedura può essere locale o globale; basta che rientri nell'ambito di visibilità del codice JavaScript.
function display( message : text ) do
alert( message );
end;
#{ display('hello world') }#;

Per recuperare il valore restituito da una funzione, occorre di nuovo usare la modalità callback (vedere sopra: Esecuzione asincrona):
function add( a : number, b : number ) do
a + b;
end;
#{:number:callback
add( 1, 2, (returnValue) => {
callback( returnValue )
})
}#;

Se non avete altre elaborazioni da fare dopo la chiamata alla procedura, potete passare direttamente la funzione di callback come parametro:
function add( a : number, b : number ) do
a + b;
end;
#{:number:callback
add( 1, 2, callback )
}#;

Manipolare record e funzioni
Se disponete di un elenco di ID di record, potete chiamare una funzione Ninox per modificare ogni record uno per uno. Basta chiamare la funzione passandole l'ID.
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;
Errori di esecuzione
Se nel vostro codice si verifica un errore di esecuzione, viene restituito il testo del messaggio di errore:

