15. FR Toolbox リファレンス
FileMaker データベースとの通信に使用できる FRToolbox 関数のスイートを次に示します。
最初のセクションでは、Reactor での BlackBox の管理について紹介します。
Reactor タグ
<?reactor reactor?>
これらの Reactor タグ間のすべてが Reactor によって解釈されます。これは次のようになります。:
FileMaker calculation
Reactor タグ内で任意の FileMaker 計算を実行できます
next_week_date_var = '<?reactor Get ( CurrentDate ) + 7 reactor?>';
出力例: next_week_date_var = '22/06/2019';
Get parameter value パラメータ値を取得
任意の BlackBox パラメータの値にローカル変数としてアクセスできます。:
text_field_var = '<?reactor $text_field reactor?>';
出力例:text_field_var = 'mytext';
Get value of field name parameter フィールド名パラメータの値を取得
field_name_var = '<?reactor bbdev_Field( $field_name ) reactor?>';
出力例:field_name_var = 'Description'
Get table occurrence name of field name parameter フィールド名パラメータのテーブルオカレンス名を取得
field_name_TO_var = '<?reactor bbdev_TO( $field_name ) Reactor?>';
出力例:field_name_TO_var = 'Task';
Get ‘where’ clause based on relationship from current context to table occurrence: 現在のコンテキストからテーブルオカレンスまでのリレーションシップに基づいて「where」句を取得します。:
(これは通常、データをクエリするときに使用されます)
where_clause_var = '<?reactor bbdev_Relationship( bbdev_TO($field_name) ) reactor?>';
出力例: Task.status = 'active' and Task.type = 'booked'
Get list of initial creation values based on relationship from current context to table occurrence 現在のコンテキストからテーブル オカレンスまでのリレーションシップに基づいて、初期作成値のリストを取得する
(通常、FRTB.create()
メソッドと組み合わせて、新しいレコードを作成するときに使用されます)
creation_values_var = '<?reactor bbdev_relationshipKeyBuilder ( bbdev_TO($field_name) ) reactor?>';
出力例:
Names="status,type" Values="active","booked"
Get container field images from container field parameter value オブジェクトフィールドパラメータ値からオブジェクトフィールド画像を取得
<?reactor bbdev_LoadImages( $container_field ; $field_name ; $com.reactorize.env.loadedfilepath ) reactor?>
出力例:
<img src="task_01.png" />
<img src="task_02.png" />
<img src="task_03.png" />
($field_name
の値によって、指定されたファイル名が決まります。)
FRToolbox リクエスト
次の JavaScript メソッドを使用して、FileMaker データベースで要求を実行し、応答を処理できます。
これらのリクエストは連鎖させることができ、多くの場合、そうしなければなりません。たとえば、次のすべてのメソッドは send();
を呼び出す必要があります。実際にリクエストを送信するメソッド。
Find records レコードを検索
FRTB.find(field1, field2, field3, etc)
見つかったレコードのセットを返します。返される値は、リクエストで指定されたフィールドによって異なります。
例:
QueryData = FRTB.find( "Task::name", "Task::description" );
タスク テーブルのオカレンスが基になっているテーブルのすべてのレコードからname
とdescription
フィールドの値を取得する要求を作成します。
bbdev_Field()およびbbdev_TO()関数を使用してフィールド名とテーブルの出現を変数に格納した場合は、それらを使用できます。:
QueryData = FRTB.find( TO_name_var + "::" + name_field_var, TO_name_var + "::" + description_field_var );
Constrain records レコードの制約
.where(whereclause)
SQL WHERE
句に基づいて検索条件を制限します。
例:
QueryData = FRTB.find( "Task::name", "Task::description" ).where(Task.status = 'active');
Task テーブルのオカレンスの基になっているテーブルから、Task::status
フィールドの値が active
であるすべてのレコードからname
とdescription
フィールドの値を取得するリクエストを作成します。
bbdev_Relationship()関数 を使用して「where 句」を作成した場合は、代わりに .filter()
メソッドを使用できます。これにより、SQL スタイルの構文ではなく FM スタイルの構文を使用できます (例えば、Task::name
Task.name
よりTask::name
)
.filter(where_clause_var);
Send Request リクエストを送信
これは実際に Reactor にリクエストを送信するために使用されます。最初にリクエストを作成してから送信できます:
QueryData = FRTB.find( "Task::name", "Task::description" ).where(Task.status = 'active'); QueryData.send();
または、リクエストを生成するときに送信します。:
QueryData = FRTB.find( "Task::name", "Task::description" ).where("Task.status = 'active'").send();
これにより、リクエストが Reactor に送信されます。ただし、戻ってくるものを見るには、コールバック関数を使用する必要があります。関数を定義して呼び出すことができます。:
function CheckResponse(response) { alert ( "Response received!") ; } QueryData = FRTB.find( "Task::name", "Task::description" ).where("Task.status = 'active'").send(CheckResponse);
または、リクエスト内で無名関数を定義できます。:
QueryData = FRTB.find( "Task::name", "Task::description" ).where("Task.status = 'active'").send(function(response) { alert ( "Response received!") ; });
send()
でコールバック関数を設定すると、リクエストの応答を含むパラメーターが含まれます。 find()
リクエストで使用する場合、このレスポンスには取得したデータが含まれます。
find()
リクエストのレスポンスはオブジェクトとして返されます。このオブジェクトには、data
というプロパティが含まれています。このデータ プロパティは、オブジェクトの配列です。配列の各要素のキーは、完全なフィールド名 (テーブルのオカレンス名を含む) です。
したがって、コールバック関数で、応答の各レコードの値にアクセスするには、それらをループします。:
for ( var i=0; i < response.data.length; i++) { taskname = response.data[i]["Task::name"]; taskdescription = response.data[i]["Task::description"]; alert (taskname + ": " + taskdescription ); }
Poll Request プルリクエスト
これは、find()
リクエストが送信された後の変更のポーリングに使用されます。
ポーリングは、固定名 zModID
を持つタイムスタンプ自動入力を利用します。:
このリクエストを呼び出すと、データがクエリされた後に変更をポーリングします。新しいレコード、変更されたレコード、または削除されたレコードをポーリングできます。
QueryData = FRTB.find( TO_name_var + "::" + name_field_var, TO_name_var + "::" + description_field_var ).filter(where_clause_var).poll(PollChanges).send(function(response) { alert ( "Response received!") ; });
これにより、データがポーリングされるたびに PollChanges()
関数が呼び出されます。デフォルトでは、5000 ミリ秒 (5 秒) ごとにポーリングしますが、必要に応じて独自の間隔を設定することもできます。:
.poll(PollChanges,2000)
これにより、ポーリングが 2 秒ごとに発生するように設定されます。
PollChanges() 関数が呼び出されると、ポーラーの結果を含むオブジェクトが返されます。オブジェクトには 3 つのプロパティが含まれており、それぞれが変更されたレコードを指すrowid
値の配列です。rowid
は、各レコードの内部 FileMaker ID です。
したがって、ポーリング関数は次のようになります。:
function PollTasks(results) { for( var i=0; i<results.remove.length; i++ ){ rowid = results.remove[i]; // Do something with the deleted records rowid } for( var i=0; i<results.update.length; i++ ){ rowid = results.update[i]; // Do something with the updated records rowid } for( var i=0; i<results.create.length; i++ ){ rowid = results.remove[i]; // Do something with the new records rowid } }
実際には、これらの rowid
を使用して実際に何か便利なことをしたいと思うでしょう。例えば:
削除されたレコード:BlackBox インターフェイスから削除します
新しいレコード:各レコードをクエリして、BlackBox インターフェイスに追加します
更新されたレコード:各レコードをクエリし、BlackBox インターフェイスで更新します
Create Records レコードの作成
これは、新しいレコードを追加するために使用されます。
create()
メソッドを使用すると、オブジェクトをパラメータとして設定できます。値を設定する各フィールドは、そのオブジェクトのプロパティになります。
オブジェクトを作成してから、それをパラメーターとして渡すことができます。:
NewTask = new Object(); NewTask["Task::name"] = "New task name"; NewTask["Task::description"] = "New task description"; FRTB.create(NewTask).send({'onSuccess': function(){ alert ("Record added"); }});
Or you can define the object as you’re passing it through:
FRTB.create( ["Task::name","New task name"], ["Task::description","New Task Description"] ).send({'onSuccess': function(){ alert ("Record added"); }});
Or if you’ve used the bbdev_Field()
and bbdev_TO()
functions to store the field name(s) and table occurrence(s) into variables, you can can use those:
FRTB.create( [TO_name_var + "::" + name_field_var,"New task name"], [TO_name_var + "::" + description_field_var,"New Task Description"] ).send({'onSuccess': function(){ alert ("Record added"); }});
If you have used the bbdev_relationshipKeyBuilder() function you can also set initial values based on the relationship to a table occurrence from your current context.
For example, if your BlackBox queries a found set of tasks via a relationship, and those tasks records have a type
field, and the relationship includes a predicate that the type
field must have a value of "booked"
, then this is an implied field value when creating new records.
Otherwise, unless you explicitly set the Type
as "booked"
, the next time you query Task
records your new record won’t be included in the found set.
To set these implied values, use the bbdev_relationshipKeyBuilder() function to create a variable you can use to generate a list of initial creation values, and include this when invoking the .send()
method for a .create()
request. For example:
creation_values_var = '<?reactor bbdev_relationshipKeyBuilder ( bbdev_TO($field_name) ) reactor?>'; FRTB.create( [TO_name_var + "::" + name_field_var,"New task name"], [TO_name_var + "::" + description_field_var,"New Task Description"] ).send({'creationValues' : creation_values_var, 'onSuccess': function(){ alert ("Record added"); }});
Update Records レコードの更新
This is used for updating existing records.
The update()
method allows you to set a parameter, this is an object. Each field you want to set a value for will be a property of that object.
You need to use the .where()
or .filter()
method, in conjunction with an update()
request in order to define what records we want to update.
You can either create the object and then pass that through as your parameter:
ChangedTask = new Object(); ChangedTask["Task::description"] = "Updated task description"; FRTB.update(ChangedTask).filter("Task::name=New task name").send({'onSuccess': function(){ alert ("Record updated"); }});
Or you can define the object as you’re passing it through:
FRTB.update( ["Task::description","Updated Task Description"] ).filter("Task::name=New task name").send({'onSuccess': function(){ alert ("Record Updated"); }});
If your .where()
or .filter()
constraint refers to multiple records, all of those records will be updated.
Delete Records
This is used for deleting existing records.
The remove()
method allows you to set a parameter, this is a table occurrence of the table you wish to delete a record from.
You need to use the .where()
or .filter()
method, in conjunction with a remove()
request in order to define what records we want to delete.
FRTB.remove("Task").where("Task.name='New task name'").send({'onSuccess': function(){ alert ("Record(s) deleted"); }});
If you have used the bbdev_Relationship()
you can use this to refer to your table occurrence. If you have used the bbdev_Field()
function you can use this, as well as the .filter()
method to refer to your field:
field_name_TO_var = '<?reactor bbdev_TO( $field_name ) Reactor?>'; field_name_var = '<?reactor bbdev_Field( $field_name ) reactor?>'; FRTB.remove(field_name_TO_var).filter(field_name_TO_var + "::" + field_name_var + "=New task name").send({'onSuccess': function(){ alert ("Record(s) deleted"); }});
Calculation Request
This is used for evaluating a FileMaker calculation.
The calc()
method allows you to set a parameter, this is the calculation you wish to perform.
FRTB.calc("Get(CurrentDate)").send(function(response) { alert (response.result); })
When the result of the calculation is returned via the call back function, it is accessed via the result
property in the response object.
Perform Script Request
This is used for performing a script in FileMaker Pro from your BlackBox.
The script()
method allows you to set two parameters, the first is the name of the script, and the second is the script parameter - which your script can access with Get(ScriptParameter)
. This second parameter is optional.
FRTB.script("MyScript","MyParameter").send(function(response) { alert("Script performed"); })
Request Configurations
When submitting any Reactor request you can include the following configurations with your send
method call:
FRTB.find('dd_planets_data::name').send({ 'onsuccess' : CompletionFunction, 'onerror' : ErrorFunction, 'onrecordlock' : HandleRecordLock, 'creationvalues' : creation_values_var, 'distinct' : true, 'databasename' : 'reactor', 'layoutname' : 'reactor_layout' })
The
onsuccess
,onerror
andonrecordlock
settings can be either names of functions, or anonymous functionsThe
creationvalues
value should be a variable generated using thebbdev_relationshipKeyBuilder
functionThe
distinct
setting will be set to either true/false, and will set whether or not thedistinct
keyword is used in your queries. To the SQL-uninitiated, the query response will not include any duplicate records in its responseYou only need to set the
databasename
setting if your request is intended for the non-default database - usually only relevant toFRTB.script()
requests
Utility Methods
The following JavaScript methods can be used to perform less-common requests:
Set Default Database
You can use the following to set the default database to be used with other Reactor requests:
FRTB.setDefault("DatabaseName","reactor");
The above will explicitly make all Reactor requests apply to the ‘reactor’ database.
FRToolbox Version
You can use the following to return the version of FRToolbox being employed:
frt_no_var = FRTB.getVersion();
The above will store the FRToolbox version number in a variable.
Start Debugging
Output detailed debugging to the JavaScript console.
FRTB.startDebugging();
After you run this line of code any Reactor communications will be output to the console.
Date/Time Conversion
You can use the following methods to convert JavaScript dates/times to SQL date/time strings.
FRTB.getSQLDate(new Date());
FRTB.getSQLTime(new Date());
You can use the following method to convert a SQL date/time string into a Javascript date object.
FRTB.convertDateTime("2019-06-17 19:35:00");
Get Field and Table Occurrence
You can use the following method to return the table occurrence of a fully qualified field:
FRTB.getTOName("bb_data_schedules::id",false);
If you would like to escape character spaces so you can use it in a SQL query, set the second parameter to true
:
FRTB.getTOName("bb_data_schedules::id",true);
You can use the following method to return the field name of a fully qualified field:
FRTB.getFieldName("bb_data_schedules::id",false);
If you would like to escape character spaces so you can use it in a SQL query, set the second parameter to true
:
FRTB.getFieldName("bb_data_schedules::id",true);
Reactor Actions
This bit is for the advanced BlackBoxers.
An action is a standardised method of giving the user a method of responding to a particular interaction.
For example, if we had a BlackBox, and we wanted to give the developer control of what happens after a FRTB.find()
- but without having to delve into the JavaScript. We may want to give them the ability to specify any one of the following:
Run a script
Set a field
Set global field
Run JavaScript function
To do this, we use the FRTB.getAction
method to define the action. We may want to pass through the result of our find
request. For example:
var MyAction = FRTB.getAction( 'SetField=MyLayoutTO::CurrentRecord|GetField=bb_planets_data::name', 'myAction' ); FRTB.find( 'bb_planets_data::name', 'bb_planets_data::description', MyAction ).send(function(response) { FRTB.performAction( 'myAction', response.data[0]); });
The first line is the construction of the action. It creates an action that sets a field called CurrentRecord
on the MyLayoutTO
table occurrence.
The value we set it in that field is the name
value on the bb_planets_data
table occurrence.
It doesn’t make sense yet? That’s because this value we’re setting is the result of a find
, we’re not setting the value yet, we’re defining the field that contains the value that we will be setting.
Then we have our Reactor find
request. As our parameter, we specify the fields we want returned per usual. Additionally we also include the variable name of our new action.
In our success function, we perform our action. For the first parameter we pass through the name of our action. The second parameter is the first record from our find
response.
Our action knows that when we set our field we’re setting the value of bb_planets_data::name
from our find
response. So Reactor checks our first find
response for a bb_planets_data::name
value, and that’s what value is set onto MyLayoutTO::CurrentRecord
.
Let’s say we don’t want to set a stored field, you want to set a global field, run a FileMaker script, or run a JavaScript function using this value (bb_planets_data::name
). You simply change the parameter you set when constructing the action.
// Run FileMaker Script, passing through the field value as parameter var MyAction = FRTB.getAction( 'Script=MyScriptName|Parameter=bb_planets_data::name', 'myAction' );
// Set Global Field, passing through the field value as our global field's value var MyAction = FRTB.getAction( 'SetGlobal=$$MyGlobal|Parameter=bb_planets_data::name', 'myAction' );
// Run JavaScript function, passing through the field value as parameter var MyAction = FRTB.getAction( 'Function=checkRecord();|Parameter=bb_planets_data::name', 'myAction' );
Why would we bother to do this? As you can see in the above alternatives, you could simply ask the developer to provide the actual action as a BlackBox parameter. So when a button is clicked, and you conduct the find
, the developer can set the parameter to do any of the following for example:
Set a data/global field identifying what planet was selected
Run a FileMaker script that knows what planet was selected
Run a JavaScript function that knows what planet was selected
Obviously you could do any of these individually by altering the BlackBox code, but defining an action as a BlackBox parameter gives the user the ability to change the behaviour of your BlackBox from outside of your BlackBox.
Or you can simply deem this is as needlessly complicated and forget it forever :)