原生 JS
原生 JS 讓您可以在 Ninox 腳本中執行 JavaScript 程式碼,並與腳本共用函式與變數。如此一來,原生 JS 就能存取 Ninox 變數,並呼叫本機函式與全域函式。

限制
在原生 JS 中修改 Ninox 變數,並不會影響該 Ninox 變數。
JavaScript 只會在本機執行。把 JavaScript 加進在伺服器上執行的程式碼中不會有任何效果;同樣地,從在伺服器上執行的程式碼呼叫含有 JavaScript 的全域函式,也不會有任何效果。
哪些程式碼在本機執行、哪些在伺服器上執行,請參見下圖:

語法
執行
若要告訴 Ninox 您正切換到 JavaScript,必須把程式碼包在 #{ ... }# 之中:
#{ alert("hello world") }#;
別忘了,Ninox 是預先編譯的語言,必須事先知道每個變數與函式的型別。原生 JS 也是如此:您必須指定 JavaScript 程式碼所回傳的型別。原生 JS 預設回傳 text,但您可以在程式碼最開頭以 :[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] }#
採用這種語法時,原生 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 模式之後,Ninox 的 alert 函式只會在 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') }#;

若要取得函式的回傳值,同樣必須使用回呼模式(參見上文:非同步執行):
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 )
}#;

操作記錄與函式
如果您有一份記錄 ID 的清單,可以呼叫 Ninox 函式逐一修改每筆記錄。做法很簡單:呼叫該函式並把 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;
執行錯誤
如果您的程式碼發生執行錯誤,就會回傳錯誤訊息的文字:

