サンプルソリューションのデータは、新しいサンプルデータを作る を参照してください。
この記事で使用するソースコードは、FileMaker Data API を使う 2025年版 vol.12#残りの HTML ソースコードの PHP 化 にまとめてあります。
その後の変更(Find Records のテストと JSON ファイル)は、FileMaker Data API を使う 2025年版 vol.13 、及び、FileMaker Data API を使う 2025年版 vol.14 参照してください。
現在の構造は以下の通りです。
.
├── css
│ ├── bootstrap-common.css
│ └── fmda-form.css
├── find-records-test.php
├── find-records-test2.php
├── find-records-test3.php
├── html
│ └── edit-record.html
├── index.php
├── js
│ ├── fmda-form-check.js
│ └── fmda-select-page.js
├── json
│ ├── html-contents.json
│ ├── standings-al-east-2024.json
│ └── standings-all-2024.json
└── php
├── bs-builder-class.php
├── bs-frame-class.php
├── filemaker-data-api-class.php
├── php-functions.php
├── preferences.php
└── temporary-functions.php
利用環境
以下の環境を前提に説明しています。
- Claris FileMaker Pro 21.1.1.41 macOS
- Claris FileMaker Server 21.1.1.40 Ubuntu 22(AMD)
- サーバ: Ubuntu 22.04.5 LTS
- SSL 証明書
- リクエストする側のサーバ(任意)
開発段階では、以下を使用した方が楽でしょう。
Web ページの作成は、以下を条件とします。
- Bootstrap v5.3.3
- Bootstrap Examples Checkout を土台にしています。
- PHP 8.2.22
フォームデータを表示する
前回までの記事で、FileMaker 情報ブロックの表示が出来ているはずです。
今回は、左側のフォームデータを表示させてみます。
目標イメージは次の画像です。
Find Records リクエストで、リーグ昇順と勝利数降順で全件取得しているので、ヤンキースが 1件目になります。この画像だと、分かりにくいのですが、「勝率(任意)」に表示されている「.500」はデータではなくプレースホルダです。このプレースホルダはやめていいかもしれませんね。
やめてしまいましょう。
こんなとき弄るのは JSON です。html-contents.json
の formControls
JSON 配列の8番目のデータのキー placeholder
を弄れば、変更できます。
html-contents.json
の formControls
JSON 配列の8番目
{
"id" : "winning_percentage",
"label" : "勝率",
"type" : "text",
"name" : "winning_percentage",
"placeholder" : "",
"required" : "",
"disabled" : "",
"feedback" : "",
"option" : [
{
"value" : ""
}
]
},
FileMaker を使っている場合、こういったテキストのコンテンツは JSON 化しておくて、FileMaker Pro で管理することが容易になります。
実際には、html-contents.json
のような網羅的な JSON よりも、この場合でしたら form-controls.json
のような形に特化してあげれば、FileMaker Pro 側の処理が単純になります。
この管理情報が入っているテーブルを更新し、スクリプトで、JSON 作成〜「URL から挿入」スクリプトステップの「cURL オプション」で、サーバ上の JSON を更新してあげれば、今、手作業でやったことと同じことが FileMaker Pro 上で可能です。
それでは、フォームデータを表示するための変更を施していきましょう。
現在、temporary_functions.php
の records_find_records()
関数の中で、全件データは、$team_data
配列に入っています。
これを Form の該当コントロールの value
として渡してあげれば表示されます。但し、「リーグ」と「地区」は <select>
を使っているので、該当オプションに selected
を与える必要があります。
以上のことを、次の流れで行います。
- ファーストアクセスで、Find Records 発行で全件取得(前回記事)
- フォーム表示用のデータを抜き出して、配列に入れておく
- フォームに表示
まず、フォーム表示用データを入れる配列を用意しておきましょう。
preferences.php 66行目に追加
$response_field_data = [];
次に、temporary-functions.php
の中の records_find_records()
関数で、Find Records の処理後に、$response_field_data
へ データをセットします。
temporary-functions.php の records_find_records() 関数
function records_find_records( ): void
{
global $fmda, $response, $bearer_session_token, $database, $layout, $request_body;
global $result, $data_info, $team_data, $response_field_data;
global $info_item_content;
if ($fmda->getMessagesCode($response) === '0') {
// セッション有効なら、行いたいリクエスト実行
// レコードの検索
$response = $fmda->findRecords($database, $layout, $bearer_session_token, $request_body);
// 結果セット処理
$result = $fmda->json2array($response);
if ($fmda->getMessagesCode($response) === '0') {
$data_info = $result['response']['dataInfo'];
$team_data = $result['response']['data'];
// 追加部分
array_push($info_item_content, $data_info['database']);
array_push($info_item_content, $data_info['layout']);
array_push($info_item_content, $data_info['table']);
array_push($info_item_content, $team_data[0]['recordId']);
array_push($info_item_content, $team_data[0]['modId']);
array_push($info_item_content, $data_info['totalRecordCount']);
array_push($info_item_content, $data_info['foundCount']);
array_push($info_item_content, $data_info['returnedCount']);
$response_field_data = [
$team_data[0]['fieldData']['mlb_site_id'],
$team_data[0]['fieldData']['year'],
$team_data[0]['fieldData']['league'],
$team_data[0]['fieldData']['division'],
$team_data[0]['fieldData']['team'],
$team_data[0]['fieldData']['wins'],
$team_data[0]['fieldData']['losses'],
$team_data[0]['fieldData']['winning_percentage'],
$team_data[0]['fieldData']['runs_scored'],
$team_data[0]['fieldData']['runs_allowed'],
$team_data[0]['fieldData']['pythagorean_expectation'],
$team_data[0]['fieldData']['expected_win_loss'],
$team_data[0]['fieldData']['winning_percentage_difference']
];
}
} else {
// セッション無効なら、必要な Web データを保持して、ユーザに再ログインを促す
echo "<div class=\"alert alert-warning\" role=\"alert\">セッションが切れました。再ログインしてください。</div>\n";
}
}
これで1件目のフォームデータが、$response_field_data
に入るので、あとはフォームに渡してあげればいいだけです。
フォームは、bs-builder-class.php
の BsBuilder
クラス、CreateForm
メソッドで作っていますので、各コントロールが value
を持つように、加えて、<select>
コントロールでは、該当データが selected
されるように変更を加えます。
CreateForm() メソッド
static function CreateForm (
array &$form_prefernces,
array &$form_controls,
array &$field_data,
): void {
echo <<<_HTML_
<div class="col-md-7 col-lg-8">
<h4 class="mb-3">{$form_prefernces[0]}</h4>
<form action="{$form_prefernces[1]}" method="POST" class="needs-validation" novalidate>
<div class="row g-3">
_HTML_; // begin
$i = 0;
foreach ($form_controls as $key => $value) {
$required = '';
$secondary_label = '';
if ($value['required'] === '1')
$required = 'required';
else
$secondary_label = '<span class="text-body-secondary">(任意)</span>';
if ($value['type'] === 'select') {
echo <<<_HTML_
<div class="col-sm-6">
<label for="{$value['id']}" class="form-label">{$value['label']}{$secondary_label}</label>
<select class="form-select" id="{$value['id']}" name="{$value['name']}" {$required} {$value['disabled']}>
<option value="">選択...</option>
_HTML_;
foreach ($value['option'] as $option_key => $option_value) {
$selected = $field_data[$i] === $option_value['value'] ? 'selected' : '';
$current_value = $selected === 'selected' ? $field_data[$i] : $option_value['value'];
echo "<option value=\"{$current_value}\" {$selected} >{$option_value['value']}</option>\n";{$option_value['value']}</option>\n";
}
echo "</select>\n";
} else {
echo <<<_HTML_
<div class="col-sm-6">
<label for="{$value['id']}" class="form-label">{$value['label']}{$secondary_label}</label>
<input type="{$value['type']}" class="form-control" id="{$value['id']}" name="{$value['name']}" value="{$field_data[$i]}" placeholder="{$value['placeholder']}" {$required} {$value['disabled']}>
_HTML_;
} // if ($value['type'] === 'select')
if (!empty($required)) {
echo <<<_HTML_
<div class="invalid-feedback">
{$value['feedback']}
</div>
_HTML_;
} // if (!empty($required))
echo "</div>\n";
$i += 1;
} // foreach ($form_controls as $key => $value)
echo <<<_HTML_
</div> <!-- / .row -->
<hr class="my-4">
<button class="w-100 btn {$form_prefernces[2]} btn-lg" type="submit">{$form_prefernces[3]}</button>
</form> <!-- / .needs-validation -->
_HTML_;
}
変更部分は、まず、フォームデータを参照するための引数を追加しています。
static function CreateForm (
array &$form_prefernces,
array &$form_controls,
array &$field_data,
): void {
次に、<select>
コントロールの <option>
タグに selected
されることの判別を行なっています。ここでは、一応、value
も与えていますが、選択要素と渡す値が同じなら、与えなくても結果は一緒です。
例えば、選択要素「アメリカン・リーグ」、値「AL」のような場合は、value
が必要になるので、一応、これに対応しておこうと思います。
foreach ($value['option'] as $option_key => $option_value) {
$selected = $field_data[$i] === $option_value['value'] ? 'selected' : '';
$current_value = $selected === 'selected' ? $field_data[$i] : $option_value['value'];
echo "<option value=\"{$current_value}\" {$selected} >{$option_value['value']}</option>\n";
}
echo "</select>\n";
三項演算子で、現在の $field_data[$i]
が、選択要素 $option_value['value']
と一致するなら、$selected
を 'selected'
に、そうでなければ ''
を与えます。
値が「ニューヨーク・ヤンキース」で、選択要素も「ニューヨーク・ヤンキース」なら、selected
ということです。
この部分の HTML 出力は、例えば、リーグなら以下のようになります。
<div class="col-sm-6">
<label for="league" class="form-label">リーグ</label>
<select class="form-select" id="league" name="league" required >
<option value="">選択...</option>
<option value="アメリカン・リーグ" selected>アメリカン・リーグ</option>
<option value="ナショナル・リーグ" >ナショナル・リーグ</option>
</select>
<div class="invalid-feedback">
リーグを選択してください。
</div>
</div>
これはチェックボックスでも原理は同じになります。チェックボックスの場合は、selected
ではなく、checked
を与えます。
<select>
以外は、次の箇所を変更しています。
echo <<<_HTML_
<div class="col-sm-6">
<label for="{$value['id']}" class="form-label">{$value['label']}{$secondary_label}</label>
<input type="{$value['type']}" class="form-control" id="{$value['id']}" name="{$value['name']}" value="{$field_data[$i]}" placeholder="{$value['placeholder']}" {$required} {$value['disabled']}>
_HTML_;
一例として、チーム名の HTML 出力は次のようになります。
<div class="col-sm-6">
<label for="team" class="form-label">チーム名</label>
<input type="text" class="form-control" id="team" name="team" value="ニューヨーク・ヤンキース" placeholder="" required >
<div class="invalid-feedback">
チーム名を入力してください。
</div>
</div>
最後に、CreateForm
メソッドに引数を増やしていますから、呼び出し側も変更します。
index.php 40行目
BsBuilder::CreateForm($form_preferences, $form_controls, $response_field_data);
以上で、フォームデータが表示されるようになります。
これで積み残しは、以下になります。
・フッタのリンクからの機能切り替え
・ページネーション
・FileMaker 情報ブロックの下の「取得する」フォーム
・各機能の FIleMaker Data API リクエスト
現在、表示中の機能はレコード編集ですが、次回は、レコード更新(records - Edit Record)と、空欄になっているフィールドをどうするかという問題に取り組みたいと思います。